首先今天遇到一个些问题,就是如何在使用的时候通过我们的扩展把lua的复合型数据传递到neko虚拟机里。
这个问题match到的几个点。
1 lua堆栈trans为Table 。
包装类型这个方案这个在我们的swig里就不在做介绍了。 我们只做大自然的搬运工就好了。
首先说明的是我们不需要做第一步,因为swig已经替我们做好了,可以直接进行第二部分。
2 需要把Lua的table 序列化成 neko VM 的 Object。
在lua的世界里是没有指针和引用,没有类型这些概念的。 比如他生成一个table大概是这样子的。
local a = {
[moduName]="test",
[funcName]="t",
[funcParam]={1,2,3}
}
我们在脚本语言里可以这样定义,但是到我们的c里面呢失灵了。首先除却预先定义好的struct这种说法不讨论。我们需要解复用,我们越过lua的堆栈操作的API直接neko VM生成在的数据结构。拆分一下API可能会有一系列的getter和setter。
value getObject();
value getArray(int size);
char * getObjectString(value obj, char * k);
……
void setObjectProb(value obj, char * k, value v) ;
void setObjectInt(value obj, char * k, int v);
void setObjectString (value obj, char * k , char * v);
void setObjectBoolean(value obj, char * k, int v);
void setObjectNumber(value obj, char * k, double v);
void print(value v) ;
这些低级api 可以通过lua直接使用,通过组合这些操作,table数据我们就描述清楚了,table里怎么嵌套大致就几种。当然在使用neko VM的某些定义的时候一定要看仔细定义。比如需要的是指针或者引用,而swig有点不太care这块。
3 如何区分动态的类型。
这里有个问题就是 neko的 value 类型
typedef enum {
VAL_INT = 0xFF,
VAL_NULL = 0,
VAL_FLOAT = 1,
VAL_BOOL = 2,
VAL_STRING = 3,
VAL_OBJECT = 4,
VAL_ARRAY = 5,
VAL_FUNCTION = 6,
VAL_ABSTRACT = 7,
VAL_INT32 = 8,
VAL_PRIMITIVE = 6 | 16,
VAL_JITFUN = 6 | 32,
VAL_32_BITS = 0xFFFFFFFF
} val_type;
如果在纯c工程里是可以直接使用的。但是在我们的环境里是不可以使用的。比如 table 就必须是 table , 搞个tppedef 或者 void * 到这里交叉编译不通过。
local module = example.loadModule("mymodule.n", "test")
print(module);
example.executeModule(module);
print("==============");
local paramA = example.getObject();
--example.test();
--example.setObjectBoolean(paramA,"b",1);
--example.setObjectNumber(paramA,"d",3.14);
example.setObjectString(paramA,"funcName","f");
local arr = example.getArray(0);
example.setObjectProb(paramA,"funcParam", arr);
example.setObjectString(paramA,"moduleName","test");
--example.setObjectInt(paramA,"I",1000);
print("-------------------------");
print(example.getObjectString(paramA,"moduleName"));
print(example.getObjectString(paramA,"funcName"));
print(example.getObjectString(paramA,"funcParam"));
print("-------------------------");
example.callModuleMethod(paramA);
print("call func done");
print(example.getObjectString(paramA,"moduleName"));
最后来个测试结果
vm test
userdata: 0x14ba9b8
add module done test
userdata: 0x14ba728
==============
setObjectProbString
[k]=funcName
[v]=f run
setObjectProb run
setObjectProbString
[k]=moduleName
[v]=test run
-------------------------
getObjectString run
string : test (4 bytes)
test
getObjectString run
string : f (1 bytes)
f
getObjectString run
array : size 0
越来越接近真相了。