CLib 模块

CLib扩展,可以用来调用第三方动态库。

用CLib来加载一个第三方动态库

  1. function loadLib()
  2. {
  3. var systemName = SystemName();
  4. var libPath = GetRoot();
  5. if(systemName == "windows")
  6. {
  7. libPath += "testdll.dll";
  8. }
  9. else if(systemName == "linux")
  10. {
  11. libPath += "libtestdll.so";
  12. }
  13. else
  14. {
  15. libPath += "libtestdll.dylib";
  16. }
  17. var clibs = new CLib(libPath);
  18. if(!clibs.load())
  19. {
  20. print "load err!";
  21. return 0;
  22. }
  23. print "load success!!";
  24. }
CLib函数描述用法
load() 加载动态库 clibs.load()
free() 释放动态库 clibs.free()
findFunc(funcName,returnType,parm1Type,……) 获取导出函数,返回CLibFunc对象 var tAdd = clibs.findFunc("tAdd","int","int","int");
CLibFunc函数描述用法
callFunc(parm1,……) 调用函数 var res = tAdd.callFunc(100,300);

例子

  1. //c++函数定义
  2. int tAdd(int a,int b)
  3. {
  4. return a + b;
  5. }
  1. import CBCLib.code
  2. function main(parm)
  3. {
  4. var clibs = loadLib();
  5. var tAdd = clibs.findFunc("tAdd","int","int","int");
  6. var res = tAdd.callFunc(100,300);
  7. print "tAdd : " + res;
  8. }

结果:

  1. tAdd : 400

与C++类型的对应关系

CLib类型c++类型字节数
"int"int4
"float"float4
"byte","char"char1
"bool"bool1
"short"short2
"int64"long long8
"double"double8
"wchar"wchar_twindows:2。linux:4。macos:4
"string"char64位OS:8。32位OS:4
"wstring"wchar_t64位OS:8。32位OS:4
"pointer"任意类型指针64位OS:8。32位OS:4
"callback"回调函数64位OS:8。32位OS:4

例子2

  1. //c++函数定义
  2. const char* tTest(int a,int b,int c,float d,double e,float f,int g,int h,int i,long long j,int k,float l,double m,float n,float o)
  3. {
  4. char* buf = new char[4096];
  5. memset(buf,0,4096);
  6. sprintf(buf,"a=%d,b=%d,c=%d,d=%f,e=%lf,f=%f,g=%d,h=%d,i=%d,j=%ld,k=%d,l=%f,m=%lf,n=%f,o=%f",a,b,c,d,e,f,g,h,i,j,k,l,m,n,o);
  7. return buf;
  8. }
  9. void tfreeString(char* pStr)
  10. {
  11. delete[] pStr;
  12. }
  1. import CBCLib.code
  2. function main(parm)
  3. {
  4. var clibs = loadLib();
  5. var tTest = clibs.findFunc("tTest","string","int","int","int","float","double","float","int","int","int","int64","int","float","double","float","float");
  6. var res = tTest.callFunc(1,2,3,4.0,5.0,6.0,7,8,9,10,11,12.0,13.0,14.0,15.0);
  7. print "tTest : " + res; //虽然结果正确,但是内存泄漏了,对于需要释放的字符串不建议使用string接收
  8. //应该以pointer方式接收被new出来的字符串
  9. tTest = clibs.findFunc("tTest","pointer","int","int","int","float","double","float","int","int","int","int64","int","float","double","float","float");
  10. res = tTest.callFunc(1,2,3,4.0,5.0,6.0,7,8,9,10,11,12.0,13.0,14.0,15.0);
  11. print "tTest : " + res.readString();
  12. var tfreeString = clibs.findFunc("tfreeString","void","pointer");
  13. tfreeString.callFunc(res);
  14. }

结果:

  1. tTest : a=1,b=2,c=3,d=4.000000,e=5.000000,f=6.000000,g=7,h=8,i=9,j=10,k=11,l=12.000000,m=13.000000,n=14.000000,o=15.000000
  2. tTest : a=1,b=2,c=3,d=4.000000,e=5.000000,f=6.000000,g=7,h=8,i=9,j=10,k=11,l=12.000000,m=13.000000,n=14.000000,o=15.000000

char*可以用"string"和"pointer"接收,区别在于,"string"会复制一份,"pointer"会保留原地址

用CLibPointer来操作内存

CLibPointer描述了一个内存地址。当函数返回值为"pointer"时返回该对象,也可以主动new出来操作内存。

CLibPointer函数描述用法
addAddr(bytes) 地址增加bytes字节 ponter.addAddr(4);
subAddr(bytes) 地址减bytes字节 ponter.subAddr(4);
copyAddr() 复制当前地址到一个新的指针对象中 var newpoint = ponter.copyAddr();
malloc(bytes) 申请地址空间,如果不是空指针,则调用无效果。 ponter.malloc(4);
free() 释放内存空间 ponter.free();
isNull() 如果是空指针返回true,否则返回false var isnull = ponter.isNull();
readString() 从当前地址开始读取一个字符串,\0结束 var str = ponter.readString();
readWString() 从当前地址开始读取一个宽字符串,L'\0'结束 var wstr = ponter.readWString();
readInt() 从当前地址开始读取4个字节作为整数 var intv = ponter.readInt();
readByte() 从当前地址开始读取1个字节作为整数 var intv = ponter.readByte();
readShort() 从当前地址开始读取2个字节作为整数 var intv = ponter.readShort();
readInt64() 从当前地址开始读取8个字节作为整数 var intv = ponter.readInt64();
readPointer() 从当前地址开始读取一个地址,返回CLibPointer对象。32位OS读4个字节,64位OS读8个字节 var newpoint = ponter.readPointer();

例子3

  1. //c++函数定义
  2. int* tTestIntArray(int &size)
  3. {
  4. size = 8;
  5. int *a = new int[size];
  6. for (int i = 0 ; i < size ; i++)
  7. {
  8. a[i] = i * 50;
  9. }
  10. return a;
  11. }
  12. void tFreeIntArray(int *a)
  13. {
  14. delete[] a;
  15. }
  1. import CBCLib.code
  2. function main(parm)
  3. {
  4. var clibs = loadLib();
  5. var tTestIntArray = clibs.findFunc("tTestIntArray","pointer","pointer");
  6. //参数是一个引用,要提前申请空间
  7. var intref = new CLibPointer();
  8. intref.malloc(4);
  9. var res = tTestIntArray.callFunc(intref);
  10. //把值读出来
  11. var intCount = intref.readInt();
  12. print "tTestIntArray : intCount=>" + intCount;
  13. print res;
  14. var resRead = res.copyAddr(); //复制地址,因为读取后地址会自增,保留原地址要用来free
  15. var resStr = "tTestIntArray : return=>\n";
  16. for(var i = 0 ; i < intCount ; i++)
  17. {
  18. resStr += i + " " + resRead.readInt(true) + "\n";
  19. }
  20. print resStr;
  21. intref.free(); //自己malloc的需要释放
  22. var tFreeIntArray = clibs.findFunc("tFreeIntArray","pointer");
  23. tFreeIntArray.callFunc(res);//c代码里new出来的,调用接口释放
  24. }

结果:

  1. tTestIntArray : intCount=>8
  2. [CLibPointer]Object 0xfed220
  3. tTestIntArray : return=>
  4. 0 0
  5. 1 50
  6. 2 100
  7. 3 150
  8. 4 200
  9. 5 250
  10. 6 300
  11. 7 350

用CLibStruct来定义结构体

  1. //c++结构体定义
  2. struct testStruct
  3. {
  4. int a;
  5. int b;
  6. float c;
  7. double d;
  8. char* e;
  9. long long f;
  10. short g;
  11. char h;
  12. bool i;
  13. testStruct* self;
  14. wchar_t* j;
  15. };
  16. #pragma pack(1)
  17. struct testStruct2
  18. {
  19. int a;
  20. char b;
  21. short c;
  22. };
  1. //C++没有声明对其字节方式,一次写完参数类型即可
  2. var structInfo_testStruct = new CLibStruct("int","int","float","double","string","int64","short","byte","bool","pointer","wstring");
  3. //C++声明1字节对其,所以最后一个参数要写1
  4. var structInfo_testStruct2 = new CLibStruct("int","char","short",1);
CLibStruct函数描述用法
size() 获取结构体的字节大小 var s = structInfo.size()

用CLibArray来定义数组

  1. //c++结构体定义
  2. struct testStruct2
  3. {
  4. testStruct test1;
  5. //testStruct test2[2];
  6. int test2[3];
  7. long long test3[3];
  8. short test4[3];
  9. char test5[10];
  10. float test6[3];
  11. double test7[3];
  12. char* test8[3];
  13. bool test9[3];
  14. testStruct* test10[3];
  15. wchar_t* test11[3];
  16. wchar_t test12[10];
  17. };
  1. var arrayInfo_int = new CLibArray("int",3);
  2. var arrayInfo_int64 = new CLibArray("int64",3);
  3. var arrayInfo_short = new CLibArray("short",3);
  4. var arrayInfo_byte = new CLibArray("char",10);
  5. var arrayInfo_float = new CLibArray("float",3);
  6. var arrayInfo_double = new CLibArray("double",3);
  7. var arrayInfo_string = new CLibArray("string",3);
  8. var arrayInfo_bool = new CLibArray("bool",3);
  9. var arrayInfo_pointer = new CLibArray("pointer",3);
  10. var arrayInfo_wstring = new CLibArray("wstring",3);
  11. var arrayInfo_wchar = new CLibArray("wchar",10);
  12. //声明testStruct2结构体
  13. var structInfo_testStruct2 = new CLibStruct(
  14. structInfo_testStruct,
  15. arrayInfo_int,
  16. arrayInfo_int64,
  17. arrayInfo_short,
  18. arrayInfo_byte,
  19. arrayInfo_float,
  20. arrayInfo_double,
  21. arrayInfo_string,
  22. arrayInfo_bool,
  23. arrayInfo_pointer,
  24. arrayInfo_wstring,
  25. arrayInfo_wchar);

用CLibStructData来读取结构体数据

CLibStruct是结构体的定义,CLibStructData是结构体的实例。

  1. //构造testStruct结构体实例
  2. var structData_test = new CLibStructData(structInfo_testStruct);
  3. structData_test.setInt(0,90);
  4. structData_test.setInt(1,100);
  5. structData_test.setFloat(2,55.5);
  6. structData_test.setFloat(3,555.5);
  7. structData_test.setString(4,"2222222");
  8. structData_test.setInt(5,200);
  9. structData_test.setInt(6,230);
  10. structData_test.setInt(7,199);
  11. structData_test.setInt(8,1);
  12. structData_test.setPointer(9,structData_test.addr()); //把自己的地址复制给自己的属性
  13. print structData_test.getInt(0);
  14. print structData_test.getInt(1);
  15. print structData_test.getFloat(2);
  16. print structData_test.getFloat(3);
  17. print structData_test.getString(4);
  18. print structData_test.getInt(5);
  19. print structData_test.getInt(6);
  20. print structData_test.getInt(7);
  21. print structData_test.getBool(8);
CLibStructData函数描述用法
addr() 获取自身地址,返回CLibPointer对象 var pointer = structData_test.addr();
getInt(idx) 读取第idx个属性 var intv = structData_test.getInt(idx);
getInt64(idx) 读取第idx个属性 var int64v = structData_test.getInt64(idx);
getBool(idx) 读取第idx个属性 var boolv = structData_test.getBool(idx);
getFloat(idx) 读取第idx个属性 var floatv = structData_test.getFloat(idx);
getString(idx) 读取第idx个属性 var str = structData_test.getString(idx);
getWString(idx) 读取第idx个属性 var wstr = structData_test.getWString(idx);
getPointer(idx) 读取第idx个属性,返回CLibPointer var pointer = structData_test.getPointer(idx);
getStruct(idx) 读取第idx个属性,返回CLibStructData var pointer = structData_test.getStruct(idx);
getArray(idx) 读取第idx个属性,返回CLibArray var array = structData_test.getArray(idx);
setInt(idx,value) 修改第idx个属性 structData_test.setInt(idx,1);
setInt64(idx,value) 修改第idx个属性 structData_test.setInt64(idx,1);
setBool(idx,value) 修改第idx个属性 structData_test.setBool(idx,true);
setFloat(idx,value) 修改第idx个属性 structData_test.setFloat(idx,1.0);
setString(idx,value) 修改第idx个属性 structData_test.setString(idx,"1111");
setWString(idx,value) 修改第idx个属性 structData_test.setWString(idx,WSTRING("1111"));
setPointer(idx,value) 修改第idx个属性 structData_test.setPointer(idx,pointer);
setStruct(idx,value) 修改第idx个属性 structData_test.setStruct(idx,structData);
setArray(idx,value) 修改第idx个属性 structData_test.setArray(idx,arrayData);
setCallBack(idx,callback) 修改第idx个属性为一个回调函数 structData_test.setCallBack(idx,callback);

例子4

  1. //c++函数定义
  2. testStruct* tGetStruct()
  3. {
  4. testStruct* ptestStruct = new testStruct;
  5. ptestStruct->a = 50;
  6. ptestStruct->b = -100;
  7. return ptestStruct;
  8. }
  9. int tAddStruct(testStruct* ptestStruct)
  10. {
  11. return ptestStruct->a + ptestStruct->b;
  12. }
  13. void tfreeStruct(testStruct* ptestStruct)
  14. {
  15. delete ptestStruct;
  16. }
  1. import CBCLib.code
  2. function main(parm)
  3. {
  4. var clibs = loadLib();
  5. var tGetStruct = clibs.findFunc("tGetStruct","pointer");
  6. var pStruct = tGetStruct.callFunc();
  7. print pStruct;
  8. var pStructData = new CLibStructData(structInfo_testStruct,pStruct);//用结构体指针构建一个结构体才可以访问内容
  9. print pStructData.getInt(0);
  10. print pStructData.getInt(1);
  11. //int _STDCALL tAddStruct(testStruct* ptestStruct)
  12. var tAddStruct = clibs.findFunc("tAddStruct","int","pointer");
  13. var res = tAddStruct.callFunc(pStruct);
  14. print "tAddStruct : " + res;
  15. //c代码里new出来的,记得用c接口释放掉。
  16. var tfreeStruct = clibs.findFunc("tfreeStruct","void","pointer");
  17. tfreeStruct.callFunc(pStruct);
  18. }

结果:

  1. [CLibPointer]Object 0x10a54c0
  2. 50
  3. -100
  4. tAddStruct : -50

用CLibArrayData来读取数组

CLibArray是数组的定义,CLibArrayData是数组的实例。

  1. var arrayData_int = new CLibArrayData(arrayInfo_int); //构建int test2[3];
  2. arrayData_int.setInt(0,5000);
  3. arrayData_int.setInt(1,6000);
  4. arrayData_int.setInt(2,7000);
  5. print arrayData_int.getInt(0);
  6. print arrayData_int.getInt(1);
  7. print arrayData_int.getInt(2);
CLibArray函数描述用法
getInt(idx) 读取数组第idx位的值 var intv = arrayData.getInt(idx);
getInt64(idx) 读取数组第idx位的值 var int64v = arrayData.getInt64(idx);
getBool(idx) 读取数组第idx位的值 var boolv = arrayData.getBool(idx);
getFloat(idx) 读取数组第idx位的值 var floatv = arrayData.getFloat(idx);
getString(idx) 读取数组第idx位的值 var str = arrayData.getString(idx);
getString() 如果数组是char arr[xxx],可以按照string读取,前提是要有结束符 var str = arrayData.getString();
getWString(idx) 读取数组第idx位的值 var wstr = arrayData.getWString(idx);
getWString() 如果数组是wchar_t arr[xxx],可以按照wstring读取,前提是要有结束符 var wstr = arrayData.getWString();
getPointer(idx) 读取数组第idx位的值,返回CLibPointer var pointer = arrayData.getPointer(idx);
getStruct(idx) 读取数组第idx位的值,返回CLibStructData var struct = arrayData.getStruct(idx);
setInt(idx,value) 修改数组第idx位的值 arrayData.setInt(idx,1);
setInt64(idx,value) 修改数组第idx位的值 arrayData.setInt64(idx,1);
setBool(idx,value) 修改数组第idx位的值 arrayData.setBool(idx,true);
setFloat(idx,value) 修改数组第idx位的值 arrayData.setFloat(idx,1.0);
setString(idx,value) 修改数组第idx位的值 arrayData.setString(idx,"1111");
setString(value) 如果数组是char arr[x],可以按照string修取 arrayData.setString("1111");
setWString(idx,value) 修改数组第idx位的值 arrayData.setWString(idx,WSTRING("1111"));
setWString(value) 如果数组是wchar_t arr[x],可以按照wstring修取 arrayData.setWString(WSTRING("1111"));
setPointer(idx,value) 修改数组第idx位的值 arrayData.setPointer(idx,pointer);
setStruct(idx,value) 修改数组第idx位的值 arrayData.setStruct(idx,structData);

例子5

  1. //c++函数定义
  2. testStruct tGetStrcut2(testStruct test)
  3. {
  4. testStruct a;
  5. a.a = 5;
  6. a.b = 64;
  7. return test;
  8. }
  9. testStruct2 tGetStrcut4(testStruct2 test)
  10. {
  11. int aaa = sizeof(testStruct2);
  12. testStruct2 t;
  13. t.test1.a = 5;
  14. t.test1.b = 10;
  15. t.test2[0] = 1000;
  16. t.test2[1] = 2000;
  17. t.test2[2] = 3000;
  18. return test;
  19. }
  1. import CBCLib.code
  2. function main(parm)
  3. {
  4. var clibs = loadLib();
  5. var arrayData_int = new CLibArrayData(arrayInfo_int); //构建int test2[3];
  6. arrayData_int.setInt(0,5000);
  7. arrayData_int.setInt(1,6000);
  8. arrayData_int.setInt(2,7000);
  9. var arrayData_int64 = new CLibArrayData(arrayInfo_int64); //构建long long test3[3];
  10. arrayData_int64.setInt(0,5001);
  11. arrayData_int64.setInt(1,6001);
  12. arrayData_int64.setInt(2,7001);
  13. var arrayData_short = new CLibArrayData(arrayInfo_short); //构建short test4[3];
  14. arrayData_short.setInt(0,100);
  15. arrayData_short.setInt(1,200);
  16. arrayData_short.setInt(2,300);
  17. var arrayData_byte = new CLibArrayData(arrayInfo_byte); //构建char test5[10];
  18. arrayData_byte.setInt(0,97);
  19. arrayData_byte.setInt(1,98);
  20. arrayData_byte.setInt(2,99);
  21. //arrayData_byte.setString("abc"); //也可以设置一个字符串进去,上面三句等同于这一句
  22. var arrayData_float = new CLibArrayData(arrayInfo_float); //构建float test6[3];
  23. arrayData_float.setFloat(0,55.5);
  24. arrayData_float.setFloat(1,66.6);
  25. arrayData_float.setFloat(2,77.7);
  26. var arrayData_double = new CLibArrayData(arrayInfo_double); //构建double test7[3];
  27. arrayData_double.setFloat(0,555.55);
  28. arrayData_double.setFloat(1,666.66);
  29. arrayData_double.setFloat(2,777.77);
  30. var arrayData_string = new CLibArrayData(arrayInfo_string); //构建char* test8[3];
  31. arrayData_string.setString(0,"aaaaa");
  32. arrayData_string.setString(1,"bbbbb");
  33. arrayData_string.setString(2,"ccccc");
  34. var arrayData_bool = new CLibArrayData(arrayInfo_bool); //构建bool test9[3];
  35. arrayData_bool.setBool(0,true);
  36. arrayData_bool.setBool(1,false);
  37. arrayData_bool.setBool(2,true);
  38. var arrayData_wstring = new CLibArrayData(arrayInfo_wstring); //构建wchar_t* test11[3];
  39. arrayData_wstring.setWString(0,WSTRING("aaaaaaaa"));
  40. arrayData_wstring.setWString(1,WSTRING("bbbbbbbb"));
  41. arrayData_wstring.setWString(2,WSTRING("ccccccccc"));
  42. var arrayData_wchar = new CLibArrayData(arrayInfo_wchar); //构建wchar_t test12[10];
  43. arrayData_wchar.setInt(0,97);
  44. arrayData_wchar.setInt(1,98);
  45. arrayData_wchar.setInt(2,99);
  46. //arrayData_wchar.setWString(WSTRING("abc")); //也可以设置一个字符串进去,上面三句等同于这一句
  47. //构造testStruct结构体实例
  48. var structData_test = new CLibStructData(structInfo_testStruct);
  49. structData_test.setInt(0,90);
  50. structData_test.setInt(1,100);
  51. structData_test.setFloat(2,55.5);
  52. structData_test.setFloat(3,555.5);
  53. structData_test.setString(4,"2222222");
  54. structData_test.setInt(5,200);
  55. structData_test.setInt(6,230);
  56. structData_test.setInt(7,199);
  57. structData_test.setInt(8,1);
  58. structData_test.setPointer(9,structData_test.addr());
  59. structData_test.setWString(10,WSTRING("3333333"));
  60. var tGetStrcut2 = clibs.findFunc("tGetStrcut2",structInfo_testStruct,structInfo_testStruct);
  61. var res = tGetStrcut2.callFunc(structData_test);
  62. var arrayData_pointer = new CLibArrayData(arrayInfo_pointer); //构建testStruct* test10[3];
  63. arrayData_pointer.setPointer(0,res.addr());
  64. arrayData_pointer.setPointer(2,structData_test.addr());
  65. //构造testStruct2结构体实例
  66. var structData_test2 = new CLibStructData(structInfo_testStruct2);
  67. structData_test2.setStruct(0,res);
  68. structData_test2.setArray(1,arrayData_int);
  69. structData_test2.setArray(2,arrayData_int64);
  70. structData_test2.setArray(3,arrayData_short);
  71. structData_test2.setArray(4,arrayData_byte);
  72. structData_test2.setArray(5,arrayData_float);
  73. structData_test2.setArray(6,arrayData_double);
  74. structData_test2.setArray(7,arrayData_string);
  75. structData_test2.setArray(8,arrayData_bool);
  76. structData_test2.setArray(9,arrayData_pointer);
  77. structData_test2.setArray(10,arrayData_wstring);
  78. structData_test2.setArray(11,arrayData_wchar);
  79. //testStruct2 tGetStrcut4(testStruct2 test)
  80. var tGetStrcut4 = clibs.findFunc("tGetStrcut4",structInfo_testStruct2,structInfo_testStruct2);
  81. var res = tGetStrcut4.callFunc(structData_test2);
  82. print res;
  83. var struct = res.getStruct(0); //获取testStruct test1;
  84. print struct;
  85. print struct.getInt(0);
  86. print struct.getInt(6);
  87. var res_arraydata_int = res.getArray(1); //获取int test2[3];
  88. print res_arraydata_int;
  89. print res_arraydata_int.getInt(0);
  90. print res_arraydata_int.getInt(1);
  91. print res_arraydata_int.getInt(2);
  92. var res_arraydata_int64 = res.getArray(2); //获取long long test3[3];
  93. print res_arraydata_int64;
  94. print res_arraydata_int64.getInt(0);
  95. print res_arraydata_int64.getInt(1);
  96. print res_arraydata_int64.getInt(2);
  97. var res_arraydata_short = res.getArray(3); //获取short test4[3];
  98. print res_arraydata_short;
  99. print res_arraydata_short.getInt(0);
  100. print res_arraydata_short.getInt(1);
  101. print res_arraydata_short.getInt(2);
  102. var res_arraydata_byte = res.getArray(4); //获取char test5[10];
  103. print res_arraydata_byte;
  104. print res_arraydata_byte.getInt(0);
  105. print res_arraydata_byte.getInt(1);
  106. print res_arraydata_byte.getInt(2);
  107. print res_arraydata_byte.getInt(3);
  108. print res_arraydata_byte.getString(); //如果char数组里是一个字符串,也可以只接拿字符串出来。如果没有结束符/0 可能会出现异常
  109. var res_arraydata_float = res.getArray(5); //获取float test6[3];
  110. print res_arraydata_float;
  111. print res_arraydata_float.getFloat(0);
  112. print res_arraydata_float.getFloat(1);
  113. print res_arraydata_float.getFloat(2);
  114. var res_arraydata_double = res.getArray(6); //获取double test7[3];
  115. print res_arraydata_double;
  116. print res_arraydata_double.getFloat(0);
  117. print res_arraydata_double.getFloat(1);
  118. print res_arraydata_double.getFloat(2);
  119. var res_arraydata_string = res.getArray(7); //获取char* test8[3];
  120. print res_arraydata_string;
  121. print res_arraydata_string.getString(0);
  122. print res_arraydata_string.getString(1);
  123. print res_arraydata_string.getString(2);
  124. var res_arraydata_bool = res.getArray(8); //获取bool test9[3];
  125. print res_arraydata_bool;
  126. print res_arraydata_bool.getBool(0);
  127. print res_arraydata_bool.getBool(1);
  128. print res_arraydata_bool.getBool(2);
  129. var res_arraydata_pointer = res.getArray(9); //获取testStruct* test10[3];
  130. print res_arraydata_pointer;
  131. var res_arraydata_s_p = res_arraydata_pointer.getPointer(0);
  132. print res_arraydata_s_p;
  133. print res_arraydata_s_p.isNull();
  134. var res_arrdata_pdata = new CLibStructData(structInfo_testStruct,res_arraydata_s_p);
  135. print res_arrdata_pdata.getInt(1);
  136. print res_arrdata_pdata.getFloat(2);
  137. print res_arrdata_pdata.getPointer(9);
  138. res_arraydata_s_p = res_arraydata_pointer.getPointer(1);
  139. print res_arraydata_s_p;
  140. print res_arraydata_s_p.isNull();
  141. res_arrdata_pdata = new CLibStructData(structInfo_testStruct,res_arraydata_s_p);
  142. print res_arrdata_pdata.getInt(1);
  143. print res_arrdata_pdata.getFloat(2);
  144. print res_arrdata_pdata.getPointer(9);
  145. res_arraydata_s_p = res_arraydata_pointer.getPointer(2);
  146. print res_arraydata_s_p;
  147. print res_arraydata_s_p.isNull();
  148. res_arrdata_pdata = new CLibStructData(structInfo_testStruct,res_arraydata_s_p);
  149. print res_arrdata_pdata.getInt(1);
  150. print res_arrdata_pdata.getFloat(2);
  151. print res_arrdata_pdata.getPointer(9);
  152. var res_arraydata_wstring = res.getArray(10); //获取wchar_t* test11[3];
  153. print res_arraydata_wstring;
  154. var wstring = res_arraydata_wstring.getWString(0);
  155. print "wstring : " + wstring;
  156. var utf8str = str_convert(wstring,"wstring","utf-8");
  157. print "utf8str : " + utf8str;
  158. var wstring = res_arraydata_wstring.getWString(1);
  159. print "wstring : " + wstring;
  160. var utf8str = str_convert(wstring,"wstring","utf-8");
  161. print "utf8str : " + utf8str;
  162. var wstring = res_arraydata_wstring.getWString(2);
  163. print "wstring : " + wstring;
  164. var utf8str = str_convert(wstring,"wstring","utf-8");
  165. print "utf8str : " + utf8str;
  166. var res_arraydata_wchar = res.getArray(11);
  167. print res_arraydata_wchar;
  168. print res_arraydata_wchar.getInt(0);
  169. print res_arraydata_wchar.getInt(1);
  170. print res_arraydata_wchar.getInt(2);
  171. print res_arraydata_wchar.getInt(3);
  172. var wstring = res_arraydata_wchar.getWString();
  173. print "wstring : " + wstring;
  174. var utf8str = str_convert(wstring,"wstring","utf-8");
  175. print "utf8str : " + utf8str;
  176. }

结果:

  1. [CLibStructData]Object 0x10a6280
  2. [CLibStructData]Object 0x10a62e0
  3. 90
  4. 230
  5. [CLibArrayData]Object 0x10a6340
  6. 5000
  7. 6000
  8. 7000
  9. [CLibArrayData]Object 0x10a63a0
  10. 5001
  11. 6001
  12. 7001
  13. [CLibArrayData]Object 0x10a6400
  14. 100
  15. 200
  16. 300
  17. [CLibArrayData]Object 0x10a6460
  18. 97
  19. 98
  20. 99
  21. 0
  22. abc
  23. [CLibArrayData]Object 0x10a64c0
  24. 55.500000
  25. 66.599998
  26. 77.699997
  27. [CLibArrayData]Object 0x10a6520
  28. 555.549988
  29. 666.659973
  30. 777.770020
  31. [CLibArrayData]Object 0x10a6580
  32. aaaaa
  33. bbbbb
  34. ccccc
  35. [CLibArrayData]Object 0x10a6700
  36. true
  37. false
  38. true
  39. [CLibArrayData]Object 0x10a6760
  40. [CLibPointer]Object 0x10a67c0
  41. false
  42. 100
  43. 55.500000
  44. [CLibPointer]Object 0x10a6880
  45. [CLibPointer]Object 0x10a68e0
  46. true
  47. 0
  48. 0.000000
  49. [CLibPointer]Object 0x10a69a0
  50. [CLibPointer]Object 0x10a6a00
  51. false
  52. 100
  53. 55.500000
  54. [CLibPointer]Object 0x10a6ac0
  55. [CLibArrayData]Object 0x10a6b20
  56. wstring : a
  57. utf8str : aaaaaaaa
  58. wstring : b
  59. utf8str : bbbbbbbb
  60. wstring : c
  61. utf8str : ccccccccc
  62. [CLibArrayData]Object 0x10a6ee0
  63. 97
  64. 98
  65. 99
  66. 0
  67. wstring : a
  68. utf8str : abc

多维数组与一维数组在内存里完全相同,所以多维数组也按照一维数组处理。int[2][2]与int[4]相同,int[3][3][3]与int[27]相同。

回调函数

有时候第三方库的接口是传递一个回调函数,CBrother中使用CLibCallBack来实现这样的功能。

  1. //c++函数定义
  2. typedef int (*pCallBackFunc1)(float a,int b,int c,int d,double e,float f,int g,double h,int i,long long j,int k,float l,double m,float n,float o,float p);
  3. typedef testStruct (*pCallBackFunc2)(testStruct a,testStruct *b);
  4. //接收一个函数地址并回调回去
  5. int tTestCallBack(void *func,const char* funcName)
  6. {
  7. if(strcmp(funcName,"CallBackFunc1") == 0)
  8. {
  9. pCallBackFunc1 pFunc = (pCallBackFunc1)func;
  10. int res = pFunc(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25);
  11. return res;
  12. }
  13. else if(strcmp(funcName,"CallBackFunc2") == 0)
  14. {
  15. pCallBackFunc2 pFunc = (pCallBackFunc2)func;
  16. testStruct s1,s2;
  17. s1.a = 1;
  18. s1.b = 2;
  19. s1.c = 3;
  20. s1.d = 4;
  21. s1.e = "1111";
  22. s1.f = 6;
  23. s1.g = 7;
  24. s1.h = 8;
  25. s1.i = 9;
  26. s1.j = L"2222";
  27. s1.self = &s1;
  28. s2.a = 10;
  29. s2.b = 20;
  30. s2.c = 30;
  31. s2.d = 40;
  32. s2.e = "11110";
  33. s2.f = 60;
  34. s2.g = 70;
  35. s2.h = 80;
  36. s2.i = 90;
  37. s2.j = L"22220";
  38. s2.self = &s2;
  39. testStruct res = pFunc(s1,&s2);
  40. if (res.a == s1.a)
  41. {
  42. return 1;
  43. }
  44. return 0;
  45. }
  46. }

调用例子1:

  1. function CallBackFunc1(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)
  2. {
  3. print "CallBackFunc1 a=" + a
  4. + " b=" + b + " c=" + c + " d=" + d + " e=" + e + " f=" + f + " g=" + g + " h=" + h + " i=" + i
  5. + " j=" + j + " k=" + k + " l=" + l + " m=" + m + " n=" + n + " o=" + o + " p=" + p;
  6. return 100;
  7. }
  8. function main()
  9. {
  10. var clibs = loadLib();
  11. print "call_tTestCallBack1 begin";
  12. //c++函数原形
  13. var tTestCallBack = clibs.findFunc("tTestCallBack","int","callback","string");
  14. //声明回调函数
  15. var callback1 = new CLibCallBack(CallBackFunc1,"int","float","int","int","int","double","float","int","double",
  16. "int","int64","int","float","double","float","float","float");
  17. var res = tTestCallBack.callFunc(callback1,"CallBackFunc1");
  18. print "call_tTestCallBack1 end " + res;
  19. }

结果:

  1. call_tTestCallBack1 begin
  2. CallBackFunc1 a=10.000000 b=11 c=12 d=13 e=14.000000 f=15.000000 g=16 h=17.000000 i=18 j=19 k=20 l=2
  3. 1.000000 m=22.000000 n=23.000000 o=24.000000 p=25.000000
  4. call_tTestCallBack1 end 100

调用例子2:

  1. function CallBackFunc2(a,b)
  2. {
  3. print "CallBackFunc2 -------------------------------";
  4. print a;
  5. print a.getInt(0);
  6. print a.getInt(1);
  7. print a.getFloat(2);
  8. print a.getFloat(3);
  9. print a.getString(4);
  10. print a.getInt(5);
  11. print a.getInt(6);
  12. print a.getInt(7);
  13. print a.getBool(8);
  14. var tPointerSelf = a.getPointer(9);
  15. print tPointerSelf;
  16. var pStructData_Self = new CLibStructData(structInfo_testStruct,tPointerSelf); //用结构体指针构建一个结构体才可以访问内容
  17. print pStructData_Self.getInt(0);
  18. print pStructData_Self.getString(4);
  19. print pStructData_Self.getPointer(9);
  20. return a;
  21. }
  22. function main()
  23. {
  24. var clibs = loadLib();
  25. print "call_tTestCallBack2 begin";
  26. //c++函数原形
  27. var tTestCallBack = clibs.findFunc("tTestCallBack","int","callback","string");
  28. //声明回调函数
  29. var callback2 = new CLibCallBack(CallBackFunc2,structInfo_testStruct,structInfo_testStruct,"pointer");
  30. var res = tTestCallBack.callFunc(callback2,"CallBackFunc2");
  31. print "call_tTestCallBack2 end " + res;
  32. }

结果:

  1. call_tTestCallBack2 begin
  2. CallBackFunc2 -------------------------------
  3. [CLibStructData]Object 0xcc6a30
  4. 1
  5. 2
  6. 3.000000
  7. 4.000000
  8. 1111
  9. 6
  10. 7
  11. 8
  12. true
  13. [CLibPointer]Object 0xcc6b50
  14. 1
  15. 1111
  16. [CLibPointer]Object 0xcc6c10
  17. call_tTestCallBack2 end 1
CLibCallBack函数描述用法
CLibCallBack(cbfunc,returnType,parm1Type,……,threadDel) 构造函数,声明回调函数原形。最后一个参数为bool值,多数情况下不用写。 var callback1 = new CLibCallBack(CallBackFunc1,"int","float","int","int")

如果第三方库是在一个从未执行过CBrother代码的线程里调用回调函数,CBrother会自动为该线程创建CBrother运行时上下文,并不会自动销毁。 多数情况是在固定的几个线程里执行,这时不销毁就不用重复创建会提升执行效率。

但有些第三方库实现的糟糕,每次都是动态创建一个线程,执行完后再销毁线程,这时候CBrother的运行时上下文就需要销毁。 CLibCallBack的构造函数最后一个缺省参数为bool类型,默认是false,表示不销毁运行时环境,如果设置true则会销毁(销毁的前提是因为调用回调函数而创建了该运行时环境,如果该线程的运行时环境是其他地方创建的,此处便不会销毁)。

  1. function main()
  2. {
  3. //这个回调函数不会销毁运行时
  4. var callback = new CLibCallBack(CallBackFunc,"int","float","int","int");
  5. //最后一个参数为true则会销毁
  6. var callback = new CLibCallBack(CallBackFunc,"int","float","int","int",true);
  7. }

支持的调用约定

64位程序调用约定已经统一,只要是64位程序都支持。

32位程序支持最常用的cdecl和stdcall。其他调用方式不支持。

总结

本章节的例子都在CBrother包的sample/clibs中。

CLib库提供了非常灵活的方式来操作内存,所以它是非安全的,也就是说稍不注意就会导致进程崩溃。再者,调用第三方动态库都需要遵守调用约定,如果你把结构体的成员类型或者函数的参数类型写错的话, 也是会崩溃的,因为你的这些错误CBrother没有办法帮你检查。

当你用到了CLib库,那么你一定要有能力去避免这些崩溃。