成功编译 Node 模块和 "Module did not self-register."
Successful compiling the Node module and "Module did not self-register."
我决定在 Windows 8.1 32 位下使用 VS2015 编译器和 node-gyp 为 Node 编写本机模块。我按照 this page 的说明工作。我搜索了互联网(包括 Whosebug)以寻找解决我的问题的方法。
我使用以下版本:
- 节点:4.6.0
- 节点 gyp: 3.4.0
模块源码:
// main.c++
#include <node.h>
#include <v8.h>
void Method(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope scope(isolate);
args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, "world"));
}
void init(v8::Local<v8::Object> target) {
NODE_SET_METHOD(target, "hello", Method);
}
NODE_MODULE(sapphire, init);
// binding.gyp
{
"targets": [
{
"target_name": "sapphire",
"sources": [ "main.c++" ]
}
]
}
每次编译(node-gyp rebuild
在插件的源代码文件夹中调用)都会成功。在编译之前 Node-Gyp 打印编译为 node@4.6.0 | win32 | ia32
。在那之前一切看起来都很好。
为了测试,我写了最简单的脚本。
// test.js
try {
var sapphire = require('/build/Release/sapphire');
console.log(sapphire.hello());
} catch(err) {
console.log(err);
}
结果打印错误Error: Module did not self-register.
。我尝试用 NAN 替换 Node 和 V8(遵循 this tutorial)。但是结果是一样的。
在寻找解决我的问题的过程中,我遇到了两个可能的原因:
- 版本不正确(库与解释器相比)。不幸的是消除了这种可能性,Node-Gyp 显然使用了与我使用的解释器相同的库版本。
- 从 node_modules 重新下载模块。老实说,我不明白为什么。在安装Node-Gyp的过程中已经更新了所有必要的模块,其余的无所谓。
什么会导致此错误?该模块的源代码是从 Node (v4.6.0) 文档的教程中下载的。我还尝试做一些小改动,并使用各种非官方指南,包括 NAN。每次问题都是一样的。
node-gyp(用于构建节点插件的工具)倾向于做出一些假设,至少在编译源文件时是这样。例如,它会根据源文件的扩展名自动选择 "right" 编译器。因此,如果您有一个“.c”文件,它会使用 C 编译器;如果您有一个“.cc”文件(或者可能是“.cpp”文件),它会使用 C++ 编译器。
'.c++' 不是 C++ 源文件的通用文件扩展名,因此 node-gyp 可能会以意想不到的方式解释扩展名(可能是 C 源文件)。将扩展名更改为更常见的内容可能会有所帮助。
我决定在 Windows 8.1 32 位下使用 VS2015 编译器和 node-gyp 为 Node 编写本机模块。我按照 this page 的说明工作。我搜索了互联网(包括 Whosebug)以寻找解决我的问题的方法。
我使用以下版本:
- 节点:4.6.0
- 节点 gyp: 3.4.0
模块源码:
// main.c++
#include <node.h>
#include <v8.h>
void Method(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
v8::HandleScope scope(isolate);
args.GetReturnValue().Set(v8::String::NewFromUtf8(isolate, "world"));
}
void init(v8::Local<v8::Object> target) {
NODE_SET_METHOD(target, "hello", Method);
}
NODE_MODULE(sapphire, init);
// binding.gyp
{
"targets": [
{
"target_name": "sapphire",
"sources": [ "main.c++" ]
}
]
}
每次编译(node-gyp rebuild
在插件的源代码文件夹中调用)都会成功。在编译之前 Node-Gyp 打印编译为 node@4.6.0 | win32 | ia32
。在那之前一切看起来都很好。
为了测试,我写了最简单的脚本。
// test.js
try {
var sapphire = require('/build/Release/sapphire');
console.log(sapphire.hello());
} catch(err) {
console.log(err);
}
结果打印错误Error: Module did not self-register.
。我尝试用 NAN 替换 Node 和 V8(遵循 this tutorial)。但是结果是一样的。
在寻找解决我的问题的过程中,我遇到了两个可能的原因:
- 版本不正确(库与解释器相比)。不幸的是消除了这种可能性,Node-Gyp 显然使用了与我使用的解释器相同的库版本。
- 从 node_modules 重新下载模块。老实说,我不明白为什么。在安装Node-Gyp的过程中已经更新了所有必要的模块,其余的无所谓。
什么会导致此错误?该模块的源代码是从 Node (v4.6.0) 文档的教程中下载的。我还尝试做一些小改动,并使用各种非官方指南,包括 NAN。每次问题都是一样的。
node-gyp(用于构建节点插件的工具)倾向于做出一些假设,至少在编译源文件时是这样。例如,它会根据源文件的扩展名自动选择 "right" 编译器。因此,如果您有一个“.c”文件,它会使用 C 编译器;如果您有一个“.cc”文件(或者可能是“.cpp”文件),它会使用 C++ 编译器。
'.c++' 不是 C++ 源文件的通用文件扩展名,因此 node-gyp 可能会以意想不到的方式解释扩展名(可能是 C 源文件)。将扩展名更改为更常见的内容可能会有所帮助。