Node调用CC++ DLL

xiaoxiao2025-08-05  29

采用addon方式

构建一个测试dll暴露方法如下,生成DLL文件: #define API_EXPORT extern "C" _declspec(dllexport) API_EXPORT int doTest(int a, int b); 编写对应的addon文件test.cc #include <node.h> #include <v8.h> #include <windows.h> using namespace v8; Handle<Value> doTest(const Arguments& args) { HandleScope scope; if (args.Length() < 2) { ThrowException(Exception::TypeError(String::New("Wrong number of arguments"))); return scope.Close(Undefined()); } if (!args[0]->IsNumber() || !args[1]->IsNumber()) { ThrowException(Exception::TypeError(String::New("Wrong arguments"))); return scope.Close(Undefined()); } HINSTANCE hDLL; hDLL=LoadLibrary("testdll.dll");//加载动态链接库dlldemo.dll文件; typedef int(*doTest)(int a,int b);//函数指针 doTest test=NULL; test=(doTest)GetProcAddress(hDLL,"doTest"); if (test) { int A=test(args[0]->NumberValue(),args[1]->NumberValue()); Local<Number> num = Number::New(A); return scope.Close(num); } Local<Number> num = Number::New(0); return scope.Close(num); } void Init(Handle<Object> exports) { exports->Set(String::NewSymbol("doTest"),FunctionTemplate::New(doTest)->GetFunction()); } NODE_MODULE(addon, Init)

上述代码中Init方法里绑定方法"doTest"到我们实现的函数doTest。里面用LoadLibrary加载DLL并执行对应方法。

编写binding.gyp文件 { "targets": [ { "target_name": "test", "sources": [ "test.cc" ] } ] } 执行 node-gyp configurenode-gyp build 完成编译后会在工程目录下出现build目录 用js调用测试 var addon = require('./build/Release/hello'); console.log(addon.add(1, 2));
采用ffi方式

在实际项目中还是采用了ffi,因为对于复杂的结构体、结构体指针等在addon中没有找到清晰的文档说明,而ffi要清楚和简单的多:)

添加依赖 var ffi = require('ffi'); var ref = require('ref'); var refStruct = require('ref-struct'); var refArray = require('ref-array'); 定义结构体 var configClass = refStruct({ param1:ref.types.int, param2:ref.types.int }); var strClass = refStruct({ arr:refArray(ref.types.char, 100), }); 略 映射DLL中的方法 var DLL = ffi.Library('testdll.dll',{ 'doStrings':['string',[ref.refType(strClass)]], 'doString':['string',[ref.refType(strsClass)]], 'doResult':['int',[ref.refType(resClass)]], 'doTest':['int',[ref.refType(configClass)]], 'doParam':['int',[ref.refType(paramClass)]], 'doStruct':['string',[ref.refType(ref.refType(ref.types.void)), ref.refType(structClass)]] });

其中ref.refType(strClass)表示结构体指针

调用方法 var config = new configClass(); config.param1 = 3; config.param2 = 5; var res = DLL.doTest(config.ref());

备注:

在ffi中ref()表示取地址,而deref()表示取指针所指向的值void*采用var buf1 = new Buffer(4);表示分配了一个存储地址的内存;由第一条可知 void** 就是var let ptrBuf = buf.ref();将文件读入到一段内存,如下: var buf1 = new Buffer(100); buf1.fill(0); buf1.write('E:\\test.jpg',0,"ascii");
转载请注明原文地址: https://www.6miu.com/read-5034339.html

最新回复(0)