Hi Chad,
thanks for the answer. For now I solved the issue by implementing each in
JavaScript:
Module.MyClass.prototype.forItems=function(fn) {
var iterator;
var item;
for(iterator=this.forItems_();item=iterator.next();) fn(item);
};
This involved a non-standard iterator class, because for example
calling const Iterator &operator++() causes embind to allocate a new copy
of the iterator object to pass it to JavaScript.
This brings me to the next pain point: functions returning non-const
references cause embind to copy the returned objects. I don't need this to
ever happen and the allocated objects must be freed also. Having everything
return pointers instead feels ugly on the C++ side so it was possible to
fix in bind.h around line 328:
static WireType toWireType(const T& v) {
return new T(v);
}
changed to:
static WireType toWireType(T& v) {
return &v;
}
Assuming that was correct, it would be nice to see in upstream Emscripten
and not have to always patch it. Maybe some way to control whether the
object gets copied or not? For example adding allow_raw_pointers() could
prevent the copying. I'd try to do that but I'm pretty new to C++ so
extensively modifying bind.h is very confusing.
It also seems interesting that modern browsers now support WeakMap, which
might allow freeing memory on the C++ side when pointers passed to
JavaScript get garbage collected.
Best regards,
-Juha
keskiviikko, 23. heinäkuuta 2014 0.13.11 UTC+3 Chad Austin kirjoitti:
>
> Hi Juha,
>
> I want you to know that, while I did forget about this email you sent
> until now, I do still intend to respond. The short answer is that there's
> no obvious solution today (without JS providing an implementation of a C++
> interface), but it's definitely a top issue that comes up again and again.
>
> Maybe we could have a way to tell embind about a particular C function
> signature so it would know how to convert a JS function into a C function
> pointer?
>
>
>
> On Tue, Jul 8, 2014 at 11:36 PM, Juha Järvi <[email protected]
> <javascript:>> wrote:
>
>> Hi,
>>
>> I've got a nasty compressed list structure in C++ and would like to
>> iterate through it from JavaScript using a for-each style method, passing a
>> JavaScript function as a callback. My C++ test code is:
>>
>> #include <emscripten.h>
>> #include <emscripten/bind.h>
>>
>> class Iterable {
>> public:
>> void each(void(*fn)(int)) const {
>> fn(42);
>> }
>> };
>>
>> EMSCRIPTEN_BINDINGS(test) {
>> emscripten::class_<Iterable>("Iterable")
>> .constructor<>()
>> .function("each",&Iterable::each,emscripten::allow_raw_pointers());
>> }
>>
>> Called from JavaScript like:
>>
>> i=new Module.Iterable();
>> i.each(function(x) {console.log(x);})
>>
>> However it gives an error:
>>
>> UnboundTypeError: Cannot call Iterable.each due to unbound types: PFviE
>>
>> I understand that the callback function needs wrapping using
>> Runtime.addFunction and embind doesn't handle things automatically in this
>> case for example because lifetime of the pointer is unclear, but what would
>> be the simplest way to make this work, preferably so that if some C++
>> function returns an Iterable to JavaScript, its prototype would already
>> have an each() method with all the required wrappers?
>>
>> Best regards,
>> -Juha
>>
>>
>
> --
> Chad Austin
> Technical Director, IMVU
> http://engineering.imvu.com <http://www.imvu.com/members/Chad/>
> http://chadaustin.me
>
>
>
--
You received this message because you are subscribed to the Google Groups
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.