Skip to content

[Query] Native callback to addon layer and from there to javascript layer. #756

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jay11ca39 opened this issue Mar 18, 2018 · 9 comments
Closed

Comments

@jay11ca39
Copy link

jay11ca39 commented Mar 18, 2018

I am new to Native addon concept. I am using NAN to build my native addon.

Following are my layers:

  1. C++ shared library
  2. Native addon layer
  3. Javascript APIs
  4. Javascript Application

I have some query regarding callback mechanism:

Native C++ class

typedef std::function<void(int errorCode)> nativeCallback;
Class NativeClass 
{
  public:
       NativeClass() {}   
       setCallback(nativeCallback cb) //some function of this clas will call this callback later...
       ....................

};

Addon class

Class AddonClass
{
  public:
       AddonClass() {}   
       static addonCallback(AddonClass *pointer) {} 
       ....................

};

I tried the follwing:
Define a static function in addon layer and pass it to the native cpp layer.
Result:
I am getting the native callback in my addon layer. But when i am trying to call it to javascript using :

void AddonClass::addonCallback(AddonClass *pointer) //This object is maintained using std::bind
{

        std::cout <<"[Addon addonCallback] Before getting handle"<<std::endl;
        pointer->handle();   --------------------->   **//This is crashing** 
        std::cout <<"[Addon addonCallback] After getting handle"<<std::endl;
       v8::Local<v8::Value> argv[] = { Nan::New("onEvent").ToLocalChecked() };
       pointer->emit->Call(pointer->handle(), 1, argv);

}

When i added Nan::HandleScope scope before getting the handle it is also crashing.

Did i missed anything?
Is it necessary to use libuv library function for storing the addon handle and then to call the callbacks in javascript layer?

Note: I am trying to use event emmiter concept for giving the callbacks to javascript layer

Thanks in advance.

@jay11ca39
Copy link
Author

Hello @kkoopa ,
Do you have any suggestion for solving this issue?

@kkoopa
Copy link
Collaborator

kkoopa commented Mar 20, 2018

Most likely the v8::Function handle is a dangling reference because the v8::Function does not exist. You need to store the v8::Function handle as a persistent refererence.

@kkoopa kkoopa closed this as completed Mar 20, 2018
@jay11ca39
Copy link
Author

Hello @kkoopa ,
Thanks for your reply.
I went many sample and got confused that is why i raised a issue here.

If you understand my query, following I am trying to acheive, which is a very general scenario:

  • ability to get called back from C++ lib into the native addon
  • ability to call JS code from native addon.

To achieve this do i have to use some libuv functions [ asynworker ] like you have demonstrated here:
async_pi_estimate

Basically my C++ library is pub/sub library:

so, my C++ library subscriber side will be receiving events from socket and as addon layer will register a callback to it, it will be receiving event ..

As you specified in last comment:
Most likely the v8::Function handle is a dangling reference because the v8::Function does not exist. You need to store the v8::Function handle as a persistent refererence.

But in async_pi_estimate you have commented this:

// Executed inside the worker-thread.
  // It is not safe to access V8, or V8 data structures
  // here, so everything we need for input and output
  // should go on `this`.
  void Execute () {
    estimate = Estimate(points);
  }

I got confused whether in my addon layer callback i can access the V8 object and call the javascript callback.

Can you give me suggestions for how can i acheive my scenario as I have already tried many ways.
Thanks.

@kkoopa
Copy link
Collaborator

kkoopa commented Mar 21, 2018

You cannot access V8 during AsyncWorker::Execute, which is the routine that does the actual work. After this completes, either HandleOkCallback or HandleErrorCallback will be invoked. There you can use V8 again and call back to javascript.

The test suite contains many more examples. You might want to buffer events in a queue:
https://github.com/nodejs/nan/blob/master/test/cpp/asyncprogressqueueworkerstream.cpp
https://github.com/nodejs/nan/blob/master/test/js/asyncprogressqueueworkerstream-test.js

@jay11ca39
Copy link
Author

jay11ca39 commented Mar 21, 2018

@kkoopa ,
If i understood correctly, I can not access V8 in my class function which i passed to native [C++ library] layer.
So,

Class AddonClass
{
  public:
       AddonClass() {}   
       static addonCallback(AddonClass *pointer) {} 
       ....................

};

If I pass addonCallback to the native [C++ library] layer and i receive the callback [Which i am getting currently].
As per your comment I can not call the javascript callback from my addonCallback function although I have the class object?

@kkoopa
Copy link
Collaborator

kkoopa commented Mar 21, 2018 via email

@jay11ca39
Copy link
Author

@kkoopa ,
First thing, I am not using async worker.
Query: Is it possible to acheive the below scenario without libuv or async worker:

Class AddonClass
{
  public:
       AddonClass() {}
  
       /* This **addonCallback** is passed to c++ library and it will be called by c++ library 
       *   whenever C++ library has some data it will be called any point of time till solution runs.
       *   Inside this callback I want to call Js callback, Is it possible?
       */ 
       static addonCallback(Data data)
       {

       }
};

Please read the deails of addoncallback and let me know if any other details are required.

@kkoopa
Copy link
Collaborator

kkoopa commented Mar 23, 2018

No.

@jay11ca39
Copy link
Author

Hello @kkoopa ,
Thanks for your help.
This issue is being resolved in #1171

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants