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

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

我有下一个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)

这个问题可以解决吗?

This code should work fine in theory

不幸的是,没有。 在 JavaScript 中,接收者对方法调用很重要。您可以将其视为隐含的第一个参数。将对象的方法分配给变量 "loses" 接收者。换句话说,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.