如何在V8 Javascript引擎中公开C++类,以便可以使用new创建它?

Ste*_*nov 30 javascript c++ v8

暴露Point类的官方示例似乎假设程序中将有固定数量的实例.当在Javascript中调用new时,不清楚如何在C++代码中分配新实例.

你如何公开一个可以拥有多个实例的类?例如,一个Image类:

var img1 = new Image( 640, 480 );
var img2 = new Image( 1024, 768 );

img1.clear( "red" );
img2.clear( "black" );
Run Code Online (Sandbox Code Playgroud)

Lef*_*ium 30

这是我在将C++对象暴露给V8 Javascript时可以找到的最好的博客文章.它进入更深入的细节,并使用代码片段将其分解为更小的步骤.请注意:代码片段几乎没有任何不一致之处,我需要读几遍才能理解.事先阅读我的简短摘要可能会有所帮助:

  1. 对象必须包装在V8模板中.注意:Google示例使用ObjectTemplates,但作者解释了为什么他更喜欢FunctionTemplates.
    1. 创建一个FunctionTemplate.此模板的实例具有内部字段,用于存储C++对象的内存地址.他们也获得了类的访问方法.
    2. 创建一个函数wrapObject(),它将C++对象包装在其中一个FunctionTemplates中.
  2. 构造函数也必须包装在(不同的)V8模板中.使用不同的模板来避免不必要的递归.(在博客文章末尾描述了将两个模板组合成一个模板的方法.)
    1. 创建另一个FunctionTemplate.该模板只是将JavaScript全局范围(new将从中调用)连接到C++构造函数.
    2. 制作模板将调用的方法.该方法实际上使用C++ new运算符并调用C++类构造函数.然后它通过调用在步骤1.2中创建的wrapObject()方法来包装对象.

现在,步骤2.2中分配的内存必须是delete一段时间.更新:下一篇博文" Persistent Handles "详细介绍了这一点.

在这些博文中提到了关于实际代码的说明:

  • wrapPoint()在博客方法实际上是类似于unwrap()在实际的代码方法; wrap()
  • 要找到代码之间的其他共同点,请搜索:SetInternalFieldCount(0,constructorCall
  • 实际代码似乎通过使用MakeWeak()方法来设置执行清理的回调方法来进行内存管理.


Cli*_*olf -12

我不知道如何在 V8 Js 引擎中准确地实现这一点,但就像在 Python 世界中一样,您可以按照以下步骤操作。你的图像类:

class Image
{
public:
    Image(int w, int h);
    int Width(void) const;
};
Run Code Online (Sandbox Code Playgroud)

编写一些包装函数并将这些函数暴露给 Js 世界:

Image* Image_New(int w, int h) { return new Image(w, h); }
void Image_Delete(Image* pImage) { delete pImage; }
int Image_Width(const Image* pImage) { return pImage->Width(); }
Run Code Online (Sandbox Code Playgroud)

将以下代码添加到您的 js 文件中:

var Image = function (w, h) {
    this.image = new Image(w, h);
    this.Width = function() {
        return Image_Width(this.image);
    };
};
Run Code Online (Sandbox Code Playgroud)

现在您可以开始编写代码了。另外,上面的代码没有考虑垃圾收集机制,所以要特别注意。抱歉我的英语很蹩脚!

  • v8 比 python 快得多 (2认同)