最近项目要使用Node.js调用C生成的动态链接库,最简单的方法是使用node-ffi这个插件。尝试过程中遇到几个问题,在这里记录下。
安装
可以选择在线安装或者编译安装,我这里直接命令行敲入npm install ffi
,结果报错:
gyp ERR! stack Error: Python executable "python" is v3.5.1, which is not supported by gyp.
gyp ERR! stack You czai'dengan pass the --python switch to point to Python >= v2.5.0 & < 3.0.0.
因为之前一直用的Python3,但node-gyp不支持,只好重新下载Python2.7,然后在环境变量中修改Path,重新执行命令,经过一系列显示后└── ffi@2.0.0
安装成功。成功后可以到Node命令行中查看ffi插件的详细信息。
提示:如果遇到网络问题无法下载,可以使用淘宝NPM镜像。
测试
接下来编写动态库和测试代码,写了个简单的动态库,只有一个函数:
int func(int value){
cout << "number = " << value << endl;
return 9527;
}
上述代码作为动态库Test.dll
导出后,在VS开发人员命令提示里使用dumpbin /exports Test.dll
查看下,确保导出正确。然后编写Javascript调用该动态库:
// test.js
var ffi = require('ffi') // 或者指定路径require('C:/Users/Admin/node_modules/ffi')
var d = ffi.Library('Test',{
'func':['int',['int']]
});
console.log( d.func(12306) );
又报错
Error: Dynamic Linking Error: Win32 error 193
at new DynamicLibrary (C:\Users\Admin\node_modules\ffi\lib\dynamic_library.js:74:11)
at Object.Library (C:\Users\Admin\node_modules\ffi\lib\library.js:45:12)
at Object.<anonymous> (C:\Users\Admin\Test.js:2:13)
at Module._compile (module.js:398:26)
at Object.Module._extensions..js (module.js:405:10)
at Module.load (module.js:344:32)
at Function.Module._load (module.js:301:12)
at Function.Module.runMain (module.js:430:10)
at startup (node.js:141:18)
at node.js:1003:3
- 这个是Windows动态库方面的错误,查询Windows错误码大全,
193
这个编号的意思是不是有效的win32程序
。检查发现这里出错原因是Node.js是64位而dll是32位的,将dll编译成64位后正常输出。 - 如果调用时提示
Error: Dynamic Linking Error: Win32 error 126
,错误码为找不到指定的模块,改成传入完整路径即可,下面是我程序中的例子:
var iopath = path.join(__dirname, '/IOC.dll');
var io = ffi.Library(iopath ,{
'IOC_Init':['int32',[]],
});
ffi中的类型
ffi | type |
---|---|
int8 | Signed 8-bit Integer |
uint8 | Unsigned 8-bit Integer |
int16 | Signed 16-bit Integer |
uint16 | Unsigned 16-bit Integer |
int32 | Signed 32-bit Integer |
uint32 | Unsigned 32-bit Integer |
int64 | Signed 64-bit Integer |
uint64 | Unsigned 64-bit Integer |
float | Single Precision Floating Point Number (float) |
double | Double Precision Floating Point Number (double) |
pointer | Pointer Typestring Null-Terminated String (char *) |
除上述基本类型外,ffi中还有一些别名,点击查看TYPES