SWIG for JavaScript:加载时"Module did not self-register."



使用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-gypnode-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());"

最新更新