使用 JavascriptCore C Api 绑定本机对象

Posted

技术标签:

【中文标题】使用 JavascriptCore C Api 绑定本机对象【英文标题】:Binding native objects with JavascriptCore C Api 【发布时间】:2017-11-03 19:33:27 【问题描述】:

我正在开发一个项目,该项目将使用 javascriptCore 在本机应用程序中运行 javascript。我能够将 C 本机对象与 JSClassDefinition 类绑定,并设置要导出到 Javascript 的静态函数和值。我现在的问题是我想绑定一个具有其他结构类型属性的结构。有效的代码是这样的:

struct Person   
 string name;  
 string lastName;  
 int age;  
 int salary;  

 int getSalary()  
   
    return salary;  
   
;  
.......  

JSClassRef PersonClass()   

 static JSClassRef person_class;  
 if (!person_class)   

    JSClassDefinition classDefinition = kJSClassDefinitionEmpty;  


    static JSStaticFunction staticFunctions[] =   
         "setSalary", set_salary, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete ,  
         0, 0, 0   
    ;  


    static JSStaticValue staticValues[] =   
         "name", person_get_name, 0, kJSPropertyAttributeDontDelete ,  
         "lasName", person_get_lastName, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete ,  
         0, 0, 0, 0   
    ;  


    classDefinition.className = "Person";  
    classDefinition.attributes = kJSClassAttributeNone;  
    classDefinition.staticFunctions = staticFunctions;  
    classDefinition.staticValues = staticValues;  
    classDefinition.finalize = person_finalize;  
    classDefinition.callAsConstructor = person_CallAsConstructor;  

    person_class = JSClassCreate(&classDefinition);  
   
 return person_class;  
  

.......

JSEvaluateScript(globalContext, JSStringCreateWithUTF8CString("function changeSalary(person)  person.setSalary(200);  return true;"), nullptr, nullptr, 1, nullptr)  

........  
Person *e =  new Person();  
e->salary = 100;  
e->age = 34;  

JSValueRef changeSalaryFunc = JSObjectGetProperty(globalContext, globalObject, JSStringCreateWithUTF8CString("changeSalary"),nullptr);  
JSObjectRef object = JSValueToObject(globalContext, changeSalaryFunc, nullptr);  
JSValueRef exception = 0;  
int argumentCount = 1;  
JSValueRef arguments[argumentCount];  

JSObjectRef ref = JSObjectMake(globalContext, PersonClass(), static_cast<void*>(e));  

arguments[0] = ref;  
JSValueRef result = JSObjectCallAsFunction(globalContext, object, 0, argumentCount, arguments, &exception);  

但我面临的问题是代码应该处理这种结构。

struct Address   
 string street;  
 int number;  
;  

struct Person   
 string name;  
 string lastName;  
 int age;  
 int salary;  
 Address address;  

 int getSalary()  
   
    return salary;  
   
;  

如何绑定这种结构?因为我想使用这样的代码。

JSEvaluateScript(globalContext, JSStringCreateWithUTF8CString("function address_number(person)  return person.address.number;"), nullptr, nullptr, 1, nullptr);

感谢阅读。

【问题讨论】:

【参考方案1】:

我实现了与这些结构的绑定。我做了以下步骤。

1.- 您应该像我对 Person 所做的那样绑定 Address 结构。

2.- 您必须为 Person 结构的构造函数创建 bind 方法,并在其中启动 Address 对象并将其设置为如下属性:

// Constructor
JSObjectRef PersonCallAsConstructor(JSContextRef ctx, JSObjectRef constructor, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
Person *privObj = new Person();

        if (argumentCount >= 2) 
            if (JSValueIsString(ctx, arguments[0]))
                privObj->name = JSStringToStdString(JSValueToStringCopy(ctx, arguments[0], nullptr));

            if (JSValueIsString(ctx, arguments[1]))
                privObj->lastName = JSStringToStdString(JSValueToStringCopy(ctx, arguments[1], nullptr));
        

        // the third argument passed to the person constructor is the address street
        if (argumentCount >= 3) 
            if (JSValueIsString(ctx, arguments[2]))
                privObj->address.street = JSStringToStdString(JSValueToStringCopy(ctx, arguments[2], nullptr));
        

        // initiate a new Address object
        JSObjectRef addressObj = AddressJSObjectMake(ctx, &privObj->address);
        JSObjectSetProperty(ctx, constructor, JSStringCreateWithUTF8CString("address"), addressObj, kJSPropertyAttributeNone, nullptr);

        JSObjectSetPrivate(constructor, static_cast<void*>(privObj));

        return constructor;
    

【讨论】:

以上是关于使用 JavascriptCore C Api 绑定本机对象的主要内容,如果未能解决你的问题,请参考以下文章

iOS上的javascriptcore框架可以接入网络吗?

JavaScriptCore框架介绍

iOS上的javascriptcore框架可以访问网络吗?

脱离 WebView 的通信 JavaScriptCore

JavaScriptCore框架介绍

JavaScriptCore学习之JavaScriptCore