我们在来看看自定义的函数是如何在v8实现的。 我们首先要定义一个全局对象模板: Handle<ObjectTemplate> global = ObjectTemplate::New(); //准备一个全局 对象模板 然后就是向全局对象模板中添加自己的函数(addMyFunc的定义放在后面): addMyFunc(global); 然后我们在前文的示例代码中创建上下文的地方传入全局对象模板: Persistent<Context> context = Context::New(NULL,global); //建立上下文 我们添加的函数要符合以下的模板: Handle<Value> MyPrint(const Arguments& args) //myprint函数实体,打印所有参 数 { HandleScope handle_scope; //管理这里的Handle(函数退出时释放循环里的 Handle<String> s) for(int i=0; i<args.Length(); i++) { Handle<String> s = args[i]->ToString(); std::cout << *(String::AsciiValue(s)) << std::endl; } return Undefined(); } void addMyFunc(Handle<ObjectTemplate> global) //加入自定义函数 { global->Set(String::New("print"), FunctionTemplate::New(MyPrint)); //自 定义一个myprint函数 } 这样,我们在javascript中就可以使用这样的代码了:print("Hello World!"); 我们将前文代码中:Handle<String> source = String::New("'Hello' + ', World!'"); 改为:Handle<String> source = String::New("print(\"Hello World!\");"); 编译执行,我们遍可以看到输出了 从中我们看到,print 函数已经被执行,输出了Hello, World!,最后输出的undefined 是由于我们在代码中输出脚本执行的结果,由于print 执行返回的是undefined,所以输出 Hello, World! undefined 了它。 现在我们也大概了解了函数的添加,我们接下来就来说说如何动态调用API吧。研究过 API 调用的方式的读者肯定知道,我们首先需要得到那个函数的地址,然后将数据压入堆栈 中,跳到函数的地址去执行函数,我们这里也是如此: 首先调用LoadLibrary来加载dll文件,然后用GetProcAddress来取得函数地址,然后分 别处理一个个的数据,按调用方式的要求压入堆栈之中,笔者这里的只支持stdcall的方式。 typedefint (WINAPI *FUNC_DEF)(); typedefstruct _TA_FUNC_DATA{ int nType; PVOID data; }TA_FUNC_DATA; typedefstruct _TA_FUNC_INFO{ int nType; LPVOID lpFuncAddress; int nArgs; TA_FUNC_DATA *pArgsData; }TA_FUNC_INFO; inlinevoid SetEax(DWORD data) { __asm { mov eax, data } } Handle<Value> CallFunc(const Arguments& args) //CallFunc函数实体,调用API { HandleScope handle_scope; if (args.Length() < 2) return Undefined(); char *szDllName = _strdup(*(String::AsciiValue(args[0]->ToString()))); char *szFuncName = _strdup(*(String::AsciiValue(args[1]->ToString()))); HMODULE hModule = LoadLibraryA(szDllName); if (!hModule) { free(szDllName); free(szFuncName); return Undefined(); } LPVOID lpFuncAddress = ::GetProcAddress(hModule, szFuncName); if (!lpFuncAddress) { free(szDllName); free(szFuncName); return Undefined(); } BOOL bWideChar = (szFuncName[lstrlenA(szFuncName) - 1] == 'W'); int i_ret = 0; Handle<Array> ret_array; if (args.Length() > 2) { TA_FUNC_INFO fi; fi.lpFuncAddress = lpFuncAddress; fi.nArgs = args.Length() - 2; fi.nType = 0; fi.pArgsData = new TA_FUNC_DATA[fi.nArgs]; memset(fi.pArgsData, 0, fi.nArgs * sizeof(TA_FUNC_DATA)); BOOL bRun = TRUE; int i; ret_array = Array::New(args.Length() - 1); for(i=2; i<args.Length(); i++) { if (args[i]->IsNumber()) { fi.pArgsData[i-2].nType = 0; |