使用SWIG 3.0.12和节点8.12.0,我想用一些最小的代码库创建一个本地模块:
api.h
:
#pragma once
#include <string>
std::string foo();
api.cpp
:
#include "api.h"
std::string foo() {
return "hello world";
}
api.i
:
%module(directors="1") api
%{
#include <api.h>
%}
%include "api.h"
构建我运行的节点模块:
swig -c++ -javascript -node api.i
g++ -c -fPIC api_wrap.cxx api.cpp -I /usr/include/node -I .
g++ -shared *.o -o api.node
并尝试导入:
node -e "api = require('./api.node');"
但现在我得到
module.js:682
return process.dlopen(module, path._makeLong(filename));
^
Error: Module did not self-register.
at Object.Module._extensions..node (module.js:682:18)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at [eval]:1:7
at ContextifyScript.Script.runInThisContext (vm.js:50:33)
at Object.runInThisContext (vm.js:139:38)
at Object.<anonymous> ([eval]-wrapper:6:22)
我发现了很多关于类似错误的问题和答案,但它们似乎都与npm
以及节点模块和节点运行时的错误版本有关。
我做错了什么?
不幸的是,当前版本的swig
(3.0.12(不支持Node.js版本7或更高版本。相反,您会得到像error: no template named 'WeakCallbackData' in namespace 'v8'
这样的编译时错误
要将swig
与Node 8一起使用,可以使用主分支,swig
的更高版本(看起来这将在下一个版本中修复,可能是3.0.13(,也可以下载PR 968中更改的4个文件,并将它们安装在swig 3.0.12
附带的文件中。在我的Mac上,这些文件在/usr/local/Cellar/swig/3.0.12/share/swig/3.0.12/javascript/v8/
中
不过,在那之后,@frans还有一些工作要做。
根据SWIG文档,"使用与构建v8相同的编译器标志编译模块至关重要",为此,他们建议使用node-gyp
构建模块。
您需要创建一个binding.gyp
,如下所示:
{
"targets": [
{
"target_name": "api",
"sources": [ "api.cpp", "api_wrap.cxx" ]
}
]
}
然后,在用swig
创建包装器之后,用构建模块
node-gyp configure build
(如有必要,安装带有npm install -g node-gyp
的node-gyp
(
您可能也不希望将%module(directors="1")
用于JavaScript,也不应该将括号样式的include <file.h>
用于自己的头文件。
此外,如果要使用std::string
,则需要在接口文件中包含std_string.i
。
我建议你的api.i
作为会更好
%module api
%{
#include "api.h"
%}
%include "std_string.i"
%include "api.h"
最后,完成后,模块将处于./build/Release
中,因此使用进行测试
node -e "api = require('./build/Release/api.node'); console.log(api.foo());"