首页 > 解决方案 > 使用 JavaScriptCore 从 C 调用 JavaScript 函数

问题描述

我在外部 JavaScript 文件 sample.js 中用 JavaScript 编写了一个函数。例如:

function getNum()
{
    return 123;
}

是否可以使用 JavaScriptCore 从 C 调用 getNum 函数?如果是这样,怎么做?

我能够使用以下步骤从 JavaScript 函数调用 C 函数“HelloCallback”:

JSObjectRef globalObject = JSContextGetGlobalObject(global_context);
JSStringRef helloFunctionName = JSStringCreateWithUTF8CString("hello");
// make function object
JSObjectRef functionObject = JSObjectMakeFunctionWithCallback( 
                      global_context, helloFunctionName, &HelloCallback);

// set it as proprty of global object

JSObjectSetProperty(global_context,globalObject,
        helloFunctionName,functionObject,kJSPropertyAttributeNone, NULL );

 // make javascript(using sample.js file)
 JSStringRef statement = JSStringCreateWithUTF8CString("/home/amit/Desktop/sampleWebkitgtkExample/sample.js");

// evaluate it
JSEvaluateScript( global_context,statement,NULL,NULL,1, NULL );

C 函数“HelloCallback”在 C 文件中定义如下:

JSValueRef HelloCallback( JSContextRef ctx             
                    , JSObjectRef function         
                    , JSObjectRef thisObject       
                    , size_t argumentCount         
                    , const JSValueRef arguments[] 
                    , JSValueRef* exception)       {
// here do the C++ stuff
printf("\nHello from C function\n");

return JSValueMakeUndefined(ctx);}

sample.js 文件包含以下示例代码:

function getnum()
{
    return 123;
}
hello(); // calling C function

因此,如果我想从 C 中调用 getnum() 函数,那么我们该如何以类似的方式进行呢?

我确实喜欢这样:

JSStringRef statement = JSStringCreateWithUTF8CString("/home/amit/Desktop/sampleWebkitgtkExample/sample.js");
JSEvaluateScript( global_context,statement,NULL,NULL,1, NULL );
JSStringRef script1 = JSStringCreateWithUTF8CString("getnum()");
JSValueRef x = JSEvaluateScript(global_context, script1, NULL, NULL, 0,  NULL);
printf("\n value = %d \n",x);

但我没有得到返回值。我在某个地方出错了吗?

我确实喜欢这样,现在我可以调用 getnum 函数并获取返回值:

char* scriptUTF8 = createStringWithContentsOfFile("/home/amit/Desktop/sampleWebkitgtkExample/sample.js");
JSStringRef script = JSStringCreateWithUTF8CString(scriptUTF8);
JSValueRef  result = JSEvaluateScript(global_context, script, NULL, NULL, 1, &exception);
if (JSValueIsUndefined(global_context, result))
     printf("PASS: Test script executed successfully.\n");
else {
         printf("FAIL: Test script returned unexcpected value:\n");
         JSStringRef exceptionIString = JSValueToStringCopy(global_context, 
                                                 exception, NULL);           
         JSStringRelease(exceptionIString);
      }

JSStringRef script1 = JSStringCreateWithUTF8CString("getnum()");
JSValueRef x = JSEvaluateScript(global_context, script1, NULL, NULL, 1,  NULL);
printf("\nvalue = %f \n",JSValueToNumber(global_context,x,NULL));

createStringWithContentsOfFile 函数定义如下:

static char* createStringWithContentsOfFile(const char* fileName)
    {
        char* buffer;       
        size_t buffer_size = 0;
        size_t buffer_capacity = 1024;
        buffer = (char*)malloc(buffer_capacity);        
        FILE* f = fopen(fileName, "r");
        if (!f) {
                     fprintf(stderr, "Could not open file: %s\n", fileName);
                     return 0;
                }

        while (!feof(f) && !ferror(f)) {
        buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - 
                                                           buffer_size, f);
        if (buffer_size == buffer_capacity) { // guarantees space for 
            trailing '\0'
            buffer_capacity *= 2;
            buffer = (char*)realloc(buffer, buffer_capacity);
            assert(buffer);
        }

        assert(buffer_size < buffer_capacity);
                  }
    fclose(f);
    buffer[buffer_size] = '\0';     
    return buffer;  }

标签: javascriptcjavascriptcore

解决方案


推荐阅读