从 JS (V8) 中C++对象的引用调用函数

Call function from reference of C++ Object in JS (V8)

本文关键字:对象 引用 调用 函数 C++ JS V8      更新时间:2023-10-16

我有下一个JS代码:

my_cpp_object.my_function(); // Works fine
var func = my_cpp_object.my_function;
func(); // Error, callback have not pointer to C++ object

此代码在理论上应该可以正常工作。但不是以防my_cpp_object是我通过v8::ObjectTemplatev8::Context::Set()创建的对象,因为我通过这种方式添加到上下文中的对象存储指向C++对象实例的指针。 当我调用my_cpp_object.my_function()时,它会调用一个带有const v8::FunctionCallbackInfo<v8::Value>&参数的回调函数,该参数具有指向C++对象的指针。

但是当我调用func((时,它也调用了一个带有const v8::FunctionCallbackInfo<v8::Value>&参数的回调,但没有指向C++对象的指针(args.Holder().As<v8::Object>()->InternalFieldCount() == 0

是否可以解决此问题?

这段代码理论上应该可以正常工作

不幸的是,没有。 在 JavaScript 中,拥有一个接收器对于方法调用很重要。您可以将其视为隐式的第一个参数。将对象的方法分配给变量会"丢失"接收器。换句话说,func变量不记得它是从my_cpp_object加载的,所以func()调用无法将指向该对象的指针与调用一起传递。考虑这个纯JavaScript示例:

var o = {
x: 42, 
get: function() { return this.x; }
}
o.get();  // 42
var func = o.get;
func();  // undefined

(你得到undefined的原因是因为在func()调用中,全局对象将隐式地成为接收方,所以.x加载将从中加载一个不存在的属性,所以你会得到undefined

简而言之,如果您的C++定义方法依赖于args.Holderargs.Receiver(或者如果您的 JavaScript 定义方法以任何方式依赖于this(,则调用必须具有正确的接收器。

任何解决方案都必须发生在 JavaScript 端。如果您需要一种仅存储单个函数的方法,则可以创建一个闭包来捕获接收器:

var func = function() { return my_cpp_object.my_function(); }
func();  // Works fine.