Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to pass an associative array from a Node.js C++ addon to js code?
    primarykey
    data
    text
    <p>So, I want to pass a map from C++ code to js script. Keys are numbers and values are lists with objects that are wrapped using ordinary Node.js techniques. That's the code:</p> <pre><code>Handle&lt;Value&gt; topologicalSortedGraph( const Arguments &amp;args ) { HandleScope scope; ... QMap&lt;int, QList&lt;Actor *&gt; &gt; topologicalSortedGraph = scriptContext-&gt;getTopologicalSortedGraph(); const int schemeTiersCount = topologicalSortedGraph.size(); Local&lt;Object&gt; scheme = Object::New( ); for ( int i = 0; schemeTiersCount &gt; i; ++i ) { Local&lt;Object&gt; tier = Object::New( ); foreach ( Actor *actor, topologicalSortedGraph[i] ) { Handle&lt;Value&gt; actorInitData[] = { Int32::New( reinterpret_cast&lt;int&gt;( actor ) ) }; Handle&lt;Value&gt; wrappedActor = ActorWrap::newInstance( 1, actorInitData ); tier-&gt;Set( String::NewSymbol( actor-&gt;getId( ).toLocal8Bit( ).constData( ) ), wrappedActor ); } scheme-&gt;Set( i, tier ); } return scope.Close( scheme ); } </code></pre> <p>Then I invoke following code in the script:</p> <pre><code>var addon = require('./Addon'); ... var scheme = addon.topologicalSortedGraph(); for (var number in scheme) { for (var actor in scheme[number]) { if (actor.isReady()) { addon.tick(actor); break; } } } ... </code></pre> <p>The issue is the script cannot recognize an 'actor' object and it prints to console 'undefined' when 'actor.isReady()' is being invoked. BTW, here is the definition of 'ActorWrap' class:</p> <pre><code>class ActorWrap : public node::ObjectWrap { public: static void init( ); static Handle&lt;Value&gt; newInstance( int argc, const Handle&lt;Value&gt; *argv ); private: ActorWrap( const Actor *initActor ); ~ActorWrap( ); static Handle&lt;Value&gt; newObject( const Arguments &amp;args ); static Handle&lt;Value&gt; id( const Arguments &amp;args ); static Handle&lt;Value&gt; label( const Arguments &amp;args ); static Handle&lt;Value&gt; isDone( const Arguments &amp;args ); static Handle&lt;Value&gt; isReady( const Arguments &amp;args ); static Persistent&lt;Function&gt; CONSTRUCTOR; static const char * CLASS_NAME; const Actor * actor; }; </code></pre> <p>And implementation:</p> <pre><code>Persistent&lt;Function&gt; ActorWrap::CONSTRUCTOR; const char *ActorWrap::CLASS_NAME = "Actor"; ActorWrap::ActorWrap( const Actor *initActor ) : actor( initActor ) { } ActorWrap::~ActorWrap( ) { } void ActorWrap::init( ) { Local&lt;FunctionTemplate&gt; tpl = FunctionTemplate::New( newObject ); tpl-&gt;SetClassName( String::NewSymbol( CLASS_NAME ) ); tpl-&gt;InstanceTemplate()-&gt;SetInternalFieldCount( 1 ); tpl-&gt;PrototypeTemplate( )-&gt;Set( String::NewSymbol( "id" ), FunctionTemplate::New( id )-&gt;GetFunction( ) ); tpl-&gt;PrototypeTemplate( )-&gt;Set( String::NewSymbol( "label" ), FunctionTemplate::New( label )-&gt;GetFunction( ) ); tpl-&gt;PrototypeTemplate( )-&gt;Set( String::NewSymbol( "isDone" ), FunctionTemplate::New( isDone )-&gt;GetFunction( ) ); tpl-&gt;PrototypeTemplate( )-&gt;Set( String::NewSymbol( "isReady" ), FunctionTemplate::New( isReady )-&gt;GetFunction( ) ); CONSTRUCTOR = Persistent&lt;Function&gt;::New( tpl-&gt;GetFunction( ) ); } Handle&lt;Value&gt; ActorWrap::newInstance( int argc, const Handle&lt;Value&gt; *argv ) { HandleScope scope; Handle&lt;Value&gt; objectInitData[] = { argv[0] }; Local&lt;Object&gt; instance = CONSTRUCTOR-&gt;NewInstance( 1, objectInitData ); return scope.Close( instance ); } Handle&lt;Value&gt; ActorWrap::newObject( const Arguments &amp;args ) { HandleScope scope; const Actor *actor = reinterpret_cast&lt;Actor *&gt;( args[0]-&gt;Int32Value( ) ); Q_ASSERT( NULL != actor ); ActorWrap *obj = new ActorWrap( actor ); obj-&gt;Wrap( args.This( ) ); return args.This( ); } Handle&lt;Value&gt; ActorWrap::id( const Arguments &amp;args ) { HandleScope scope; ActorWrap* obj = ObjectWrap::Unwrap&lt;ActorWrap&gt;( args.This( ) ); return scope.Close( String::New( obj-&gt;actor-&gt;getId( ).toLocal8Bit( ).constData( ) ) ); } Handle&lt;Value&gt; ActorWrap::label( const Arguments &amp;args ) { HandleScope scope; ActorWrap* obj = ObjectWrap::Unwrap&lt;ActorWrap&gt;( args.This( ) ); return scope.Close( String::New( obj-&gt;actor-&gt;getLabel( ).toLocal8Bit( ).constData() ) ); } Handle&lt;Value&gt; ActorWrap::isDone( const Arguments &amp;args ) { HandleScope scope; ActorWrap* obj = ObjectWrap::Unwrap&lt;ActorWrap&gt;( args.This( ) ); LocalWorkflow::BaseWorker *worker = obj-&gt;actor-&gt;castPeer&lt;BaseWorker&gt;( ); Q_ASSERT( NULL != worker ); return scope.Close( Boolean::New( worker-&gt;isDone() ) ); } Handle&lt;Value&gt; ActorWrap::isReady( const Arguments &amp;args ) { HandleScope scope; ActorWrap* obj = ObjectWrap::Unwrap&lt;ActorWrap&gt;( args.This( ) ); LocalWorkflow::BaseWorker *worker = obj-&gt;actor-&gt;castPeer&lt;BaseWorker&gt;( ); Q_ASSERT( NULL != worker ); return scope.Close( Boolean::New( worker-&gt;isReady() ) ); } </code></pre> <p>I suspect that something goes wrong when I initialize a 'tier' object in the first snippet. I didn't managed to find any information about setting an object as a property of another one, so may be I was wrong when called just "obj1->Set( string, obj2 );"</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload