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

时间:2010-06-18 02:11:10

标签: javascript c++ v8

暴露Point类的official examples似乎假设程序中有一定数量的实例。在Javascript中调用 new 时,不清楚如何在C ++代码中分配新实例。

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

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

img1.clear( "red" );
img2.clear( "black" );

3 个答案:

答案 0 :(得分:30)

这是最好的blog post I could find on exposing C++ objects to 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()方法来包装对象。

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

    关于actual code alluded to in these blog posts的说明:

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

答案 1 :(得分:3)

这是一个帮我,我写了一段时间后,使得暴露和处理v8中的上下文非常容易。 希望它有所帮助。

https://gamedev.stackexchange.com/questions/2796/binding-c-and-v8-javascript-from-google/2797#2797

答案 2 :(得分:-11)

我不知道如何在V8 Js引擎中完全实现这一点,但是在Python世界中,你可以这样做。 你的Image类:

class Image
{
public:
    Image(int w, int h);
    int Width(void) const;
};

编写一些包装函数并将这些函数公开给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(); }

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

var Image = function (w, h) {
    this.image = new Image(w, h);
    this.Width = function() {
        return Image_Width(this.image);
    };
};

现在你可以让代码工作了。 另外,上面的代码没有考虑垃圾收集机制,所以要特别注意它。请为我的borken英语做好准备!