Binding native objects with JavascriptCore C Api

好久不见. 提交于 2019-12-11 15:48:22

问题


I'm working on a project that is going to use JavascriptCore to run javascript in a native app. I'm able to bind a C native object with the JSClassDefinition class and set up the static functions and values that I want to export to Javascript. My problem now is that I want to bind a struct that has attributes of type other structs. The code that works is this :

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);  

But I'm facing the problem that the code should handle this structure.

struct Address {  
 string street;  
 int number;  
};  

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

 int getSalary()  
 {  
    return salary;  
 }  
};  

How can I bind this kind of structure? because I want to use a code like this.

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

Thanks for reading.


回答1:


I achieved to get the binding with these structures. I made the follow steps to do it.

1.- You should bind the Address structure as I did with Person.

2.- You have to create the bind method for the constructor for the Person structure and inside it initiate the Address object and set it as property like this:

// 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;
    }


来源:https://stackoverflow.com/questions/47103252/binding-native-objects-with-javascriptcore-c-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!