【问题标题】:V8 - Exposing a non-void C++ function to the Javascript codeV8 - 向 Javascript 代码公开一个非 void C++ 函数
【发布时间】:2021-06-17 03:19:07
【问题描述】:

我已经成功让 V8 运行任意 Javascript 文件。当我尝试公开一个 C++ 函数以便它可以由 Javascript 代码运行时,问题就来了。

我定义了以下简单的玩具函数,

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);
}

然后,我尝试将其添加到全局对象模板中,如下所示。

        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);

fvoid 函数时,这个确切的模式工作得非常好,但是现在我要求它给出一个返回值,我得到了以下错误。

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(

V8 文档中的samples 没有任何非空示例。事实上,我只知道返回类型应该是Handle&lt;Value&gt;,因为2011年的this示例。它基本上使用了与我添加全局函数相同的模式(我确实尝试将Local&lt;ObjectTemplate&gt;更改为Handle&lt;ObjectTemplate&gt;,但这并没有解决问题),所以我不确定为什么我的不工作。

我不知道如何继续。任何帮助将不胜感激。

【问题讨论】:

    标签: c++ binding v8 function-templates


    【解决方案1】:

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

    返回void。您的 args 具有 ReturnValue 属性。您可以在其中设置您的返回值。

    args.GetReturnValue().Set( 2 );
    

    我发现 google 代码往往会大量更改 API,因此查看当前文档和/或源代码是最好的选择。

    【讨论】:

    • 你真是天赐之物,谢谢。我无法找到任何关于它如何在任何地方工作的解释,并且当前文档中的样本也没有帮助。对于任何具有最新 V8 代码的项目,您有什么建议可以作为示例参考吗?
    • @cisco 不,我只是在您的错误消息中搜索了一些术语并阅读了文档。从来没有亲自接触过v8。困难的部分是阅读当前而非十年前的文档。
    • 这是有道理的,我想我的谷歌搜索没有那么强。不过,v8.dev/docs/embed 还不到十年,仍然存在令人沮丧的信息不足。不过,在 github 上查看十年前的样本可能不是最聪明的主意。但无论如何,感谢您的帮助。
    • Chrome 代码搜索也可以帮助您找到现有 API 的用户。 test-api.cc 是 V8 转储详细测试的地方:source.chromium.org/chromium/chromium/src/+/main:v8/test/cctest/…
    • FWIW,我在您已经链接到的 V8 samples 中统计了 8 次 GetReturnValue().Set(...) 的用法; v8.dev/docs/embed 提到了三遍。
    猜你喜欢
    • 1970-01-01
    • 2013-03-18
    • 2021-07-26
    • 2014-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多