我是個菜鳥,這幾天,一直在搞JS接口的使用,自己創建了父對象和子對象,並在頁面上對其傳參數(參數包括數值、對象),然後在所定義對象的方法中獲取值,測試成功。感受頗深,自己專門寫了一個創建對象文檔,現將內容共享出來,互相學習。
創建一級對象:
**枚舉所創對象的屬性和方法,
enum{
//.......
};
*創建對象實體:
typedef struct tagClassInstanceCtx{
//.......
} EisClassInstanceCtx;
**構造函數初始化
void *JSClassObject_fConstruct(JSVirtualMachine *vm, int argc, JSNode *argv)
{
EisClassInstanceCtx *ictx;
int isize=0;
ictx=(EisClassInstanceCtx*)js_vm_calloc(vm,1,sizeof(*ictx));
return ictx;
}
static
void JSClassObject_fConstruct3(JSVirtualMachine *vm, int argc, JSNode *argv, void **inst, JSBuiltinInfo *parentInfo, JSNode *parentNode)
{
EisClassInstanceCtx *ictx;
ictx=(EisClassInstanceCtx*)js_vm_calloc0(vm,1,sizeof(*ictx));
*inst = ictx;
js_vm_make_builtin_node3(vm, parentInfo, argc,argv, parentNode);
}
**指針保護
不能能在Mark函數外部使用js_mark_ptr函數
static
void JSClassObject_fMark(JSVirtualMachine *vm, void *instance)
{
if (instance!=NULL) {
EisClassInstanceCtx *ictx;
ictx = (EisClassInstanceCtx *) instance;
if (js_vm_mark_ptr(vm, ictx)!=1) return;
}
}
**對象的處理函數主要有三種:讀取屬性值,設置屬性值,調用對象的方法。
讀取屬性值:
static
int JSDvbTestObject_fGetProperty(JSVirtualMachine *vm, JSNode *self, int index, JSSymbol prop, JSNode *node)
{
EisDvbTestInstanceCtx *ictx;
ictx = (EisDvbTestInstanceCtx *) self->u.vbuiltin.instance; //獲取自定義結構實體
switch( index )
{
case JSP_DVB_Test_id:
//添加處理
break;
default:
return JSP_PROP_NOT_FOUND;
}
Return JSP_PROP_FOUND;
}
設置屬性:
static
int JSDvbTestObject_fPutProperty(JSVirtualMachine *vm, JSNode *self, int index, JSSymbol prop, JSNode *node)
{
EisDvbTestInstanceCtx *ictx;
ictx = (EisDvbTestInstanceCtx *) self->u.vbuiltin.instance;
switch( index )
{
case JSP_DVB_Test_id:
//添加處理
break;
default:
return JSP_PROP_NOT_FOUND;
}
Return JSP_PROP_FOUND;
}
用同樣的方法處理對象的方法:
static
int JSDvbTestObject_fInvokeMethod(JSVirtualMachine *vm, JSNode *self, int index, int argc, JSNode *argv, JSNode *result)
{
}
//創建並初始化對象
int jsclient_define_Class(JSVirtualMachine *vm, JSNode *result)
{
#if !defined(OLD_STYLE_JS)
JSObjectInfo2 info2[1];
JSObjectInfo *info = info2->baseInfo;
#else
JSObjectInfo info[1];
#endif
JSBuiltinInfo *builtin;
EisDvbInstanceCtx *ictx;
#if !defined(OLD_STYLE_JS)
memset(info2,0,sizeof(*info2));
#else
memset(info,0,sizeof(*info));
#endif
info->fMark = JSClassObject_fMark;
info->fGetProperty = JSClassObject_fGetProperty;
info->fPutProperty = JSClassObject_fPutProperty;
info->fInvokeMethod = JSClassObject_fInvokeMethod;
info->maxProps = JSP_Class_id-Class_PROP_NONE-1;
#if !defined(OLD_STYLE_JS)
info2->fConstruct3 = JSClassObject_fConstruct3;
builtin = JSBuiltinInfo_create2(vm, info2);
#else
info->fConstruct = JSClassObject_fConstruct;
builtin = JSBuiltinInfo_create(vm, info);
#endif
#define DEFINE_PROPERTY(m) JSBuiltinInfo_setProperty3B(builtin, vm, #m, JSP_Class_##m,JS_PROP_ATTR_NOCACHE)
DEFINE_PROPERTY(name);
DEFINE_PROPERTY(id);
DEFINE_PROPERTY(Student);
#undef DEFINE_PROPERTY
#define DEFINE_METHOD(m) JSBuiltinInfo_setMethod3(builtin, vm, #m, JSM_Class_##m)
DEFINE_METHOD(addStudent);
DEFINE_METHOD(removeStudent);
DEFINE_METHOD(totalStudent);
#undef DEFINE_METHOD
JSVirtualMachine_defineBuiltinInfo(vm, "Class", builtin);
ictx = (EisDvbInstanceCtx *) js_vm_calloc(vm, 1,sizeof(*ictx));
result->type = JS_TYPE_BUILTIN;
result->u.vbuiltin.info = builtin;
result->u.vbuiltin.instance = ictx;
return 0;
}
注意:在創建並初始化對象時,必須將設置屬性、獲取屬性、方法函數註冊,另外必須給result->u.vbuiltin.instance賦值,且不能爲空。
int jsclient_init_Class(JSVirtualMachine *vm, JSNode *result)
{
#if defined(OLD_STYLE_JS)
EisClassInstanceCtx *me;
JSBuiltinInfo *builtin;
builtin = JSVirtualMachine_lookupBuiltinInfo(vm, "Class");
me = (EisClassInstanceCtx*) js_vm_calloc(vm, 1,sizeof(*me));
result->type = JS_TYPE_BUILTIN;
result->u.vbuiltin.info = builtin;
result->u.vbuiltin.instance = me;
#else
JSNode argv[1];
argv[0].type = JS_TYPE_OBJECT;
js_vm_make_builtin_node2(vm, "Class", 1, argv, result);
#endif
return 0;
}
創建對象時:需將自己創建的對象頭文件天劍在eis_jsi.h中,在文件
Jsplugin_api.h中聲明函數
int jsclient_define_Class(JSVirtualMachine *vm, JSNode *result)
在lib_ipanel files下的jsplugin.c文件中註冊對象
jsclient_define_Class(vm, &node1); //Class對象註冊
JSBuiltinInfo_setProperty(builtin, vm, "Class", &node1);
一級對象的
Int jsclient_init_Class(JSVirtualMachine*vm, JSNode *result);函數在在Jsplugin_api.h中的聲明並不是必須的
至此,一級對象創建成功 。下面創建子對象,
其實創建子對象與一級對象基本相同,不同之處在於:
在創建並初始化對象時,給result->u.vbuiltin.instance賦值,可爲空;
將子對象添加到一級對象的屬性中,並在設置屬性、獲取屬性函數的其中一箇中初始化。切記,子對象也需要將自己創建的對象頭文件天劍在eis_jsi.h中,並且初始化函數
Int jsclient_init_Student(JSVirtualMachine*vm, JSNode *result);也需要在Jsplugin_api.h中聲明,最後將
jsclient_define_Student(vm, &node1); //Class對象註冊
JSBuiltinInfo_setProperty(builtin, vm, "Student", &node1);
在lib_ipanel files下的jsplugin.c文件中註冊.
則一級對象和子對象創建成功並可使用。