1

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 Answer 1

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;
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.