1

I'm trying to register a JavaScript callback function to be called from a C++ class later. I'm using nbind to make a node.js addon. This some sample code I've written of some more complex code that needs to accomplish the same thing:

the c++ code (testing.cc):

#include "nbind/api.h"
#include <string>
#include <iostream>

class Test
{
    nbind::cbFunction *callback;

public:
    Test() {}

    //this dummy var is only here so that doCallback() will be recognized as a function
    void doCallback(int dummyVar)
    {
        std::cout << "Calling Javascript callback" << std::endl;
        //call javascript code
        if (callback != nullptr)
        {
            (*callback)("Hi there!\n");
        }

        return;
    }

    void enrollCallback(nbind::cbFunction &cb)
    {
        callback = &cb;
        return;
    }

};

#include "nbind/nbind.h"

NBIND_CLASS(Test) {
    construct<>();
    method(doCallback);
    method(enrollCallback);
    method(unenrollCallback);
}

the JavaScript code (test.js):

var nbind = require('nbind');

function printMessage(message) {
    console.log(message);
}

var lib = nbind.init().lib;

var test = lib.Test();

test.enrollCallback(printMessage);

try{
    test.doCallback(11);
} catch(err) {
    console.log(err);
}

When I run the above code in a command line, I don't get any output at all. When I run the code like this: node inspect test.js and enter the continue command, I get the following error when the callback function is called:

Error: read ECONNRESET
    at _errnoException (util.js:992:11)
    at TCP.onread (net.js:618:25)

When I step through my program, I get the following error to the console:

TypeError: test.doCallback is not a function
     at Object.<anonymous> (C:\Users\mrcole\Desktop\testy\test.js:22:10)
     at Module._compile (module.js:649:14)
     at Object.Module._extensions..js (module.js:663:10)
     at Module.load (module.js:565:32)
     at tryModuleLoad (module.js:505:12)
     at Function.Module._load (module.js:497:3)
     at Function.Module.runMain (module.js:693:10)
     at startup (bootstrap_node.js:191:16)
     at bootstrap_node.js:612:3

Where am I going wrong, and why is node acting inconsistantly?

1 Answer 1

2

To answer my own question, don't use nbind for calling a Node JavaScript callback function in this manner. This is an asynchronous call (correct me if I'm wrong) and nbind does not, as of June 2018, support asynchronous callbacks.

A good alternative is to implement one of the AsyncWorker classes provided by NAN.

Here is some sample code:

class MyAsyncWorker : public Nan::AsyncProgressWorkerBase<T>
{
  public:

    MyAsyncWorker(Nan::Callback *callback_, const char *resource_name = "My Async Worker") 
    : AsyncProgressWorkerBase(callback_, resource_name)
    {
    }

    ~MyAsyncWorker()
    {
    }

    //Do work, or process notifications here
    void Execute(const ExecutionProgress &progress)
    {
        //do work. when you have something to report, 
        //call ExecutionProgress::Send( T * data, size_t count) to eventually call
        //the HandleProgressCallback function.
    }

    //Call JavaScript callback from this function
    void HandleProgressCallback(T *data, size_t count) 
    {
        Nan::HandleScope scope;

        v8::Local<v8::Value> argv[] = {
            //initialize your data to passback to callback here
        };
        callback->Call(count,argv,async_resource);
    }

    //This is called when you are done executing
    virtual void HandleOKCallback() 
    {
        Nan::HandleScope scope;

        v8::Local<v8::Value> argv[] = {
            //Prepare final values to be returned
        };
        callback->Call(1,argv,async_resource);
    }
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.