译序

有些网友对为什么D2JSP能执行JavaScript脚本程序感到奇怪,因此我翻译了这篇文章,原文在​​这里​​。这篇教程手把手教你怎样利用SpiderMonkey创建一个能执行JavaScript脚本的C++程序,并让JavaScript脚本操纵你的C++程序的内部数据、操作。从这篇教程能够看到在SpiderMonkey引擎的帮助下,让C++程序支持JavaScript脚本是一件非常easy的事,更棒的是SpiderMonkey也能够在Macintosh和Unix平台使用。

SpiderMonkey是​​Gecko​​(​​Firefox​​浏览器的内核)的JavaScript脚本引擎,具体文档请看​​这里​​。

下面为翻译内容。

------------------------------------------------

本教程的目的是教你怎样用JavaScript做为脚本语言使你的C++程序自己主动化。

SpiderMonkey

SpiderMonkey是Mozilla项目的一部分,用C语言写成,是负责运行JavaScript脚本的引擎。另外另一个叫Rhino的Java引擎。

SpiderMonkey的最新版本号可在​​这里​​下载。它是以源码形式公布的,因此你必须自己编译它(译注:事实上网上有非常多编译好的二进制版本号,google一下js32.dll就可找到)。Visual C++用户能够在src文件夹下找到Workspace项目project文件来编译,编译结果会产生一个叫'js32.dll'的dll文件。

SpiderMonkey也能够在Macintosh和Unix上使用,想了解怎样在这些平台上进行编译请阅读Readme.html。

在C++中运行JavaScript程序

步骤1-创建JavaScript runtime(执行时实例)

初始化一个JavaScript runtime可用JS_NewRuntime方法,该方法将为runtime分配内存,同一时候还得指定一个字节数,当内存分配超过这个数字时垃圾收集器会自己主动执行。



SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSRuntime *rt = JS_NewRuntime(1000000L);

SpiderMonkey-让你的C++程序支持JavaScript脚本_ideif ( rt == NULL )

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    // Do some error reporting

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06}

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide


步骤2-创建context(上下文环境)

Context指明了脚本执行所需的栈大小,即分配给脚本执行栈的私有内存数量。每一个脚本都和它自己的context相关联。

当一个context正在被某个脚本或线程使用时,其它脚本或线程不能使用该context。只是在脚本或线程结束时,该context能够被下一个脚本或线程重用。

创建一个新context可用JS_NewContext方法。context必须关联到一个runtime,调用JS_NewContext方法时还必须指定栈的大小。



SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSContext *cx = JS_NewContext(m_rt, 8192);

SpiderMonkey-让你的C++程序支持JavaScript脚本_ideif ( cx == NULL )

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    // Do some error reporting

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06}


步骤3-初始化全局对象

在一个脚本開始执行前,必须初始化一些大多数脚本会用到的通用的JavaScript函数和内置(build-in)类对象。

全局对象是在一个JSClass结构中描写叙述的。该结构能够按下面方式初始化:



SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSClass globalClass =

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    "Global", 0,

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    JS_PropertyStub,  JS_PropertyStub,

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    JS_PropertyStub, JS_PropertyStub,

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    JS_EnumerateStub, JS_ResolveStub,

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    JS_ConvertStub,  JS_FinalizeStub

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06};

如今创建和初始化这个全局对象:
JSObject *globalObj = JS_NewObject(cx, &globalClass, 0, 0);
JS_InitStandardClasses(cx, globalObj);


步骤4-运行脚本

运行脚本的一种途径是使用JS_EvaluateScript方法:



SpiderMonkey-让你的C++程序支持JavaScript脚本_idestd::string script = "var today = Date(); today.toString();"

SpiderMonkey-让你的C++程序支持JavaScript脚本_idejsval rval;

SpiderMonkey-让你的C++程序支持JavaScript脚本_ideuintN lineno = 0;

SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSBool ok = JS_EvaluateScript(cx, globalObj, script.c_str(), 

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide                              script.length(), "script", lineno, &rval);


在这个脚本中,假设运行正确的话当天数据会保存在rval中。rval包括最后一个运行函数的结果。JS_EvaluteScript返回JS_TRUE代表运行成功,返回JS_FALSE则代表有发生错误。

从rval得到对应的字符串值能够用以下的方法。在这里我不想解释全部细节,想获得更具体的信息请自己查API文档。



SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSString *str = JS_ValueToString(cx, rval);

SpiderMonkey-让你的C++程序支持JavaScript脚本_idestd::cout << JS_GetStringBytes(str);


步骤5-清理脚本引擎

程序结束前必须对脚本引擎做一些清理工作:
JS_DestroyContext(cx);
JS_DestroyRuntime(rt);


在C++中定义一个在JavaScript中用的类

这个样例中用到的类定义例如以下:



SpiderMonkey-让你的C++程序支持JavaScript脚本_ideclass Customer

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05public:

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    int GetAge() ...{ return m_age; }

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    void SetAge(int newAge) ...{ m_age = newAge; }

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    std::string GetName() ...{ return m_name; }

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    void SetName(std::string newName) ...{ m_name = newName; }

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05private:

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    int m_age;

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    std::string m_name;

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06};


步骤1-JavaScript类

从Customer类派生一个你想在JavaScript中用的新的C++类,或者创建一个包括一个Customer类型成员变量的新类。

给JavaScript用的类得有一个JSClass结构,为此得创建一个JSClass类型的静态成员变量,该变量会被其它类用到,因此还得把它声明为public变量。别的类能够用该结构来推断对象的类型(见JS_InstanceOf API)。



SpiderMonkey-让你的C++程序支持JavaScript脚本_ide// JSCustomer.h

SpiderMonkey-让你的C++程序支持JavaScript脚本_ideclass JSCustomer

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05public:

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    JSCustomer() : m_pCustomer(NULL) 

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    ...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_55    }

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    ~JSCustomer()

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    ...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        delete m_pCustomer;

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        m_pCustomer = NULL;

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_55    }

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    static JSClass customerClass;

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05protected:

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    void setCustomer(Customer *customer) 

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    ...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        m_pCustomer = customer; 

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_55    }

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    Customer* getCustomer()

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    ...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        return m_pCustomer; 

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_55    }

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05private:

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    Customer *m_pCustomer;

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06};


该JSClass结构里包括了JavaScript类的名字、标志位以及给脚本引擎用的回调函数的名字。举个样例,脚本引擎使用回调函数从类中获取某个属性值。

在C++类的实现文件里定义JSClass结构例如以下:



SpiderMonkey-让你的C++程序支持JavaScript脚本_ide// JSCustomer.cpp

SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSClass JSCustomer::customerClass = 

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    "Customer", JSCLASS_HAS_PRIVATE,

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        JS_PropertyStub, JS_PropertyStub,

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        JSCustomer::JSGetProperty, JSCustomer::JSSetProperty,

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        JS_EnumerateStub, JS_ResolveStub, 

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        JS_ConvertStub, JSCustomer::JSDestructor

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06};


用到的回调函数是JSCustomer::JSGetProperty,JSCustomer::JSSetProperty和JSCustomer::JSDestructor。脚本引擎调用JSGetProperty获取属性值,调用JSSetProperty设置属性值,调用JSDestructor析构JavaScript对象。

JSCLASS_HAS_PRIVATE标志位会让脚本引擎分配一些内存,这样你能够在JavaScript对象中附加一些自己定义数据,比方能够用它来保存类指针。

回调函数以C++的类静态成员函数方式存在:



SpiderMonkey-让你的C++程序支持JavaScript脚本_idestatic JSBool JSGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);

SpiderMonkey-让你的C++程序支持JavaScript脚本_idestatic JSBool JSSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);

SpiderMonkey-让你的C++程序支持JavaScript脚本_idestatic JSBool JSConstructor(JSContext *cx, JSObject *obj, uintN argc, 

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide                            jsval *argv, jsval *rval);

SpiderMonkey-让你的C++程序支持JavaScript脚本_idestatic void JSDestructor(JSContext *cx, JSObject *obj);


步骤2-初始化你的JavaScript对象

创建另外一个叫JSInit的静态方法,见以下的样例,该方法将在应用程序创建JavaScript runtime时被调用。



SpiderMonkey-让你的C++程序支持JavaScript脚本_idestatic JSObject *JSInit(JSContext *cx, JSObject *obj, JSObject *proto);


JSInit方法的实现大约例如以下:


SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSObject *JSCustomer::JSInit(JSContext *cx, JSObject *obj, JSObject *proto)

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    JSObject *newObj = JS_InitClass(cx, obj, proto, &customerClass,

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        JSCustomer::JSConstructor, 0,

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        JSCustomer::customer_properties, JSCustomer::customer_methods,

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        NULL, NULL);

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    return newObj;

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06}


对象在脚本中被具象化(译注:instantiated,简而言之就是对象new出来的时候)的时候,静态方法JSConstructor会被调用。在这种方法中能够用JS_SetPrivate API给该对象附加一些自己定义数据。



SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSBool JSCustomer::JSConstructor(JSContext *cx, JSObject *obj, uintN argc, 

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide                                 jsval *argv, jsval *rval)

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    JSCustomer *p = new JSCustomer();

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    p->setCustomer(new Customer());

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    if ( ! JS_SetPrivate(cx, obj, p) )

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        return JS_FALSE;

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    *rval = OBJECT_TO_JSVAL(obj);

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    return JS_TRUE;

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06}


JSConstructor构造方法能够带多个參数,用来初始化类。眼下为止已经在堆上创建了一个指针,还须要一种途径来销毁它,这能够通过JS_Destructor完毕:


SpiderMonkey-让你的C++程序支持JavaScript脚本_idevoid JSCustomer::JSDestructor(JSContext *cx, JSObject *obj)

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    JSCustomer *p = JS_GetPrivate(cx, obj);

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    delete p;

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    p = NULL;

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06}


步骤3-加入属性

加入一个JSPropertySpec类型的静态成员数组来存放属性信息,同一时候定义属性ID的枚举变量。



SpiderMonkey-让你的C++程序支持JavaScript脚本_idestatic JSPropertySpec customer_properties[];

SpiderMonkey-让你的C++程序支持JavaScript脚本_ideenum

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    name_prop,

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    age_prop

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06};


在实现文件里例如以下初始化该数组:



SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSPropertySpec JSCustomer::customer_properties[] = 

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{ 

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    ...{ "name", name_prop, JSPROP_ENUMERATE },

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    ...{ "age", age_prop, JSPROP_ENUMERATE },

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    ...{ 0 }

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06};


数组的最后一个元素必须为空,当中每一个元素是一个带有3个元素的数组。第一个元素是给JavaScript用的名字。第二个元素是该属性的唯一ID,将传递给回调函数。第三个元素是标志位,JSPROP_ENUMERATE代表脚本在枚举Customer对象的全部属性时能够看到该属性,也能够指定JSPROP_READONLY来表明该属性不同意被脚本程序改变。

如今能够实现该属性的getting和setting回调函数了:



SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSBool JSCustomer::JSGetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    if (JSVAL_IS_INT(id)) 

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    ...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        Customer *priv = (Customer *) JS_GetPrivate(cx, obj);

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        switch(JSVAL_TO_INT(id))

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35        ...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        case name_prop:

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05            break;

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        case age_prop:

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05            *vp = INT_TO_JSVAL(priv->getCustomer()->GetAge());

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05            break;

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_55        }

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_55    }

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    return JS_TRUE;

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06}

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide

SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSBool JSCustomer::JSSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    if (JSVAL_IS_INT(id)) 

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    ...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        Customer *priv = (Customer *) JS_GetPrivate(cx, obj);

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        switch(JSVAL_TO_INT(id))

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35        ...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        case name_prop:

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05            break;

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        case age_prop:

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05            priv->getCustomer()->SetAge(JSVAL_TO_INT(*vp));

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05            break;

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_55        }

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_55    }

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    return JS_TRUE;

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06}


建议在属性的回调函数中返回JS_TRUE。假设返回JS_FALSE,则当该属性在对象中没找到时(脚本引擎)不会进行搜索。

步骤4-加入方法

创建一个JSFunctionSpec类型的静态成员数组:



SpiderMonkey-让你的C++程序支持JavaScript脚本_idestatic JSFunctionSpec customer_methods[];


在实现文件里例如以下初始化该数组:



SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSFunctionSpec wxJSFrame::wxFrame_methods[] = 

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    ...{ "computeReduction", computeReduction, 1, 0, 0 },

SpiderMonkey-让你的C++程序支持JavaScript脚本_初始化_34SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_35    ...{ 0 }

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06};


最后一个元素必须为空,当中每一个元素是一个带有5个元素的数组。第一个元素是给脚本程序用的方法名称。第二个是一个全局或者静态成员函数的名称。第三个是该方法的參数个数。最后两个能够忽略。

在类中创建一个静态方法:



SpiderMonkey-让你的C++程序支持JavaScript脚本_idestatic JSBool computeReduction(JSContext *cx, JSObject *obj, uintN argc, 

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide                               jsval *argv, jsval *rval);


该函数成功时返回JS_TRUE,否则返回JS_FALSE。注意真正的JavaScript方法的返回值保存在rval參数中。

该方法的一个实现样例:



SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSBool JSCustomer::computeReduction(JSContext *cx, JSObject *obj, uintN argc, 

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide                                    jsval *argv, jsval *rval)

SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_03SpiderMonkey-让你的C++程序支持JavaScript脚本_数组_04...{

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    JSCustomer *p = JS_GetPrivate(cx, obj);

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    if ( p->getCustomer()->GetAge() < 25 )

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        *rval = INT_TO_JSVAL(10);

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    else

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05        *rval = INT_TO_JSVAL(5);

SpiderMonkey-让你的C++程序支持JavaScript脚本_c++_05    return JS_TRUE;

SpiderMonkey-让你的C++程序支持JavaScript脚本_ide_06}


使用样例

以下的脚本使用了前面创建的对象:



SpiderMonkey-让你的C++程序支持JavaScript脚本_idevar c = new Customer();

SpiderMonkey-让你的C++程序支持JavaScript脚本_idec.name = "Franky";

SpiderMonkey-让你的C++程序支持JavaScript脚本_idec.age = 32;

SpiderMonkey-让你的C++程序支持JavaScript脚本_idevar reduction = c.computeReduction();


别忘了在创建context时初始化JavaScript对象:



SpiderMonkey-让你的C++程序支持JavaScript脚本_ideJSObject *obj = JSCustomer::JSInit(cx, global);


类常量

JavaScript类型

这一章解释在JavaScript中会用到的几种类型:Integer,String,Boolean,Double,Object和Function。

构建中。。。。。。

垃圾回收

构建中。。。。。。

下载

​main.cpp​​演示怎样运行一个javascript程序。​​JSCustomer.h​​演示Customer的JavaScript类的定义。​​JSCustomer.cpp​​演示JSCustomer的实现。​​Customer.h​​是Customer C++类的定义。​​example.js​​示例脚本程序。