Search code examples
c++bindingv8function-templates

V8 - Exposing a non-void C++ function to the Javascript code


I have already successfully gotten V8 to run arbitrary Javascript files. The trouble comes when I try to expose a C++ function so that it can be run by the Javascript code.

I define the following simple toy function,

v8::Handle<v8::Value> f(const v8::FunctionCallbackInfo<v8::Value>& args)
{
    v8::Isolate* isolate = args.GetIsolate();
    v8::HandleScope scope(isolate);
    
    return v8::Number::New(isolate,2);
}

Then, I attempt to add it to a global object template as follows.

        v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
            global->Set(isolate, "f",
                        v8::FunctionTemplate::New(isolate, f) );

        v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);

This exact pattern worked perfectly fine when f was a void function, but now that I ask for it to give a return value, I get the following error.

cisco/test.cpp: In function ‘int main(int, char**)’:
cisco/test.cpp:52:61: error: invalid conversion from ‘v8::Handle<v8::Value> (*)(const v8::FunctionCallbackInfo<v8::Value>&) {aka v8::Local<v8::Value> (*)(const v8::FunctionCallbackInfo<v8::Value>&)}’ to ‘v8::FunctionCallback {aka void (*)(const v8::FunctionCallbackInfo<v8::Value>&)}’ [-fpermissive]
                         v8::FunctionTemplate::New(isolate, f) );
                                                             ^
In file included from cisco/test.cpp:2:0:
./include/v8.h:6495:34: note:   initializing argument 2 of ‘static v8::Local<v8::FunctionTemplate> v8::FunctionTemplate::New(v8::Isolate*, v8::FunctionCallback, v8::Local<v8::Value>, v8::Local<v8::Signature>, int, v8::ConstructorBehavior, v8::SideEffectType, const v8::CFunction*, uint8_t, uint8_t, uint8_t)’
   static Local<FunctionTemplate> New(

The samples from the V8 docs do not have any non-void examples. In fact, I only know that the return type should be Handle<Value> because of this example from 2011. It basically uses the same pattern I did to add the global function (I did try changing Local<ObjectTemplate> to Handle<ObjectTemplate>, but this didn't fix it), so I'm not sure why mine isn't working.

I'm somewhat at a loss for how to proceed. Any help would be appreciated.


Solution

  • https://v8docs.nodesource.com/node-16.0/dd/d0d/classv8_1_1_function_callback_info.html

    Return void. Your args has a ReturnValue property. You can set your return value into it.

    args.GetReturnValue().Set( 2 );
    

    I find google code tends to change APIs a lot, so looking at current docs and/or source is your best bet.