JavaScript 程序调用 C 函数
视频锁定
{$ currentTime | date:'mm:ss' $}
{$ timeLeft | date:'mm:ss' $}
从 JS 中调用 C 函数较上一节为复杂,我们来看一个较为有趣的例子:SpiderMonkey 中原生的 JavaScript 的全局变量中没有 print 函数,我们可以使用 C 的 printf 来实现这个功能。我们定义了一个函数 print, print 使用 logging 函数,而 logging 函数是定义在 C 语 言中的,接受一个字符串作为参数,打印这个字符串到标准输出上:
//log user log in information
logging("user jack login on 2010/7/6");
//user do nothing else
nothing();
//log user log out information
logging("user jack logout on 2010/7/7");
function print(){
for(var i = 0; i < arguments.length; i++){
logging(arguments[i]);
}
}
print("hello", "all", "my", "friend");
在 C 语言中,我们定义 logging 函数和 nothing 函数的原型如下:
/**
* define an exposed function to be used in scripts
* print out all the incoming arguments as string.
*/
static JSBool logging(JSContext *context, JSObject *object, uintN argc, jsval *argv, jsval *value){
int i = 0;
JSString *jss;
for(i = 0; i < argc; i++){
jss = JS_ValueToString(context, argv[i]);
printf("message from script environment : %s\n", \
JS_GetStringBytes(jss));
}
return JS_TRUE;
}
/**
* define an exposed function to be used in scripts
* do nothing but print out a single line.
*/
static JSBool nothing(JSContext *context, JSObject *object, uintN argc, jsval *argv, jsval *value){
printf("got nothing to do at all\n");
return JS_TRUE;
}
从函数的签名上可以看出,C 中暴露给 JS 使用的函数,参数的个数,及对应位置上的类型, 返回值都是固定的。所有的从 C 中暴露给 JS 的函数都需要“实现这个接口”。 定义好了函数之后,还需要一些设置才能在 JS 中使用这些函数。首先定义一个 JSFunctionSpec 类型的数组,然后通过 JS_DefineFunctions 将这些函数放到 global 对象上,然后在 JS 代码中就可以访问上边列出的 C 函数了。具体步骤如下:
static JSFunctionSpec functions[] = {
{"logging", logging, LOG_MINARGS, 0, 0},
{"nothing", nothing, NOT_MINARGS, 0, 0},
{0, 0, 0, 0, 0}
};
//define function list here
if(!JS_DefineFunctions(context, global, functions)){
return -1;
}
运行结果如下:
message from script environment : user jack login on 2010/7/6 got nothing to do at all
message from script environment : user jack logout on 2010/7/7
message from script environment : hello
message from script environment : all message from script
environment : my message from script
environment : friend
在线练习
{$ activeFileHint $}