How to use mixed C++ & .Net dll in node.js? (Error: abort() has been called)
How to use mixed C++ & .Net dll in node.js? (Error: abort() has been called)
我想在 Visual Studio 2015 年使用包含 C++ 和 C# 代码的 dll 创建本机节点扩展。我无法在去年的 my own instructions 之后使用它,它基于最新的 node-gyp
.
当不使用 /clr
选项时,我可以 运行 像下面这样的程序。
console.log("1");
const addon = require('./build/Release/addon');
console.log("2");
启用/clr
时,只会执行对日志的第一次调用。在调试模式下编译 dll 时,我收到以下消息:
如何修复/调试此问题?
(我知道有优势,但我正在尝试采用 node-gyp 方式)
在 VS2015 中尝试所有(?)编译器和链接器选项失败后,我找到了如何设置我的 binding.gyp
,以使 .Net 正常工作:
{
"targets": [
{
"target_name": "addon",
"sources": [ "hello.cc" ],
"msbuild_settings": {
"ClCompile": {
"CompileAsManaged": "true",
"ExceptionHandling": "Async",
},
},
}
]
}
我通过成功执行以下托管和非托管代码的组合来验证构建:
#include <node.h>
#include <v8.h>
namespace demo {
#pragma managed
void callManaged()
{
System::String^ result = gcnew System::String("hola");
System::Console::WriteLine("It works: " + result);
}
#pragma unmanaged
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
callManaged();
args.GetReturnValue().Set(String::NewFromUtf8(isolate, "woooooorld"));
}
void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "hello", Method);
}
NODE_MODULE(addon, init)
}
除非真的必须使用 node-gyp,否则现在 cmake-js 和 node-addon-api(提供 ABI,因此您无需为新的 Node.js 版本重建) 应该被使用。 CMakeLists.txt for cmake-js 编译混合 native/managed 代码:
cmake_minimum_required(VERSION 2.8)
project (my-addon)
set(SOURCE_FILES src/main.cc)
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
set_target_properties(${PROJECT_NAME} PROPERTIES
PREFIX ""
SUFFIX ".node"
COMMON_LANGUAGE_RUNTIME "") # "pure" and "safe" unsupported in VS 2017
target_include_directories(${PROJECT_NAME}
PRIVATE ${CMAKE_SOURCE_DIR}/node_modules/node-addon-api
PRIVATE ${CMAKE_JS_INC})
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB})
从一个package.json
开始
{
"name": "my-addon",
"version": "1.0.0",
"description": "My node.js addon",
"main": "main.js",
"scripts": {
"test": "node main.js",
"install": "cmake-js compile"
}
}
main.js
喜欢
var addon = require('bindings')('my-addon');
console.log("hello: " + addon.doSomething());
一个src/main.cc
喜欢
#include <napi.h>
namespace myaddon
{
#pragma managed
void callManaged()
{
System::String^ result = gcnew System::String("hola");
System::Console::WriteLine("It works: " + result);
}
#pragma unmanaged
Napi::String MyMethod(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
callManaged();
return Napi::String::New(env, "world");
}
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "doSomething"),
Napi::Function::New(env, MyMethod));
return exports;
}
NODE_API_MODULE(myaddon, Init)
}
建造,运行
npm install bindings
npm install node-addon-api
npm install cmake-js
npm install
要执行,运行
npm test
我想在 Visual Studio 2015 年使用包含 C++ 和 C# 代码的 dll 创建本机节点扩展。我无法在去年的 my own instructions 之后使用它,它基于最新的 node-gyp
.
当不使用 /clr
选项时,我可以 运行 像下面这样的程序。
console.log("1");
const addon = require('./build/Release/addon');
console.log("2");
启用/clr
时,只会执行对日志的第一次调用。在调试模式下编译 dll 时,我收到以下消息:
如何修复/调试此问题?
(我知道有优势,但我正在尝试采用 node-gyp 方式)
在 VS2015 中尝试所有(?)编译器和链接器选项失败后,我找到了如何设置我的 binding.gyp
,以使 .Net 正常工作:
{
"targets": [
{
"target_name": "addon",
"sources": [ "hello.cc" ],
"msbuild_settings": {
"ClCompile": {
"CompileAsManaged": "true",
"ExceptionHandling": "Async",
},
},
}
]
}
我通过成功执行以下托管和非托管代码的组合来验证构建:
#include <node.h>
#include <v8.h>
namespace demo {
#pragma managed
void callManaged()
{
System::String^ result = gcnew System::String("hola");
System::Console::WriteLine("It works: " + result);
}
#pragma unmanaged
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
void Method(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
callManaged();
args.GetReturnValue().Set(String::NewFromUtf8(isolate, "woooooorld"));
}
void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "hello", Method);
}
NODE_MODULE(addon, init)
}
除非真的必须使用 node-gyp,否则现在 cmake-js 和 node-addon-api(提供 ABI,因此您无需为新的 Node.js 版本重建) 应该被使用。 CMakeLists.txt for cmake-js 编译混合 native/managed 代码:
cmake_minimum_required(VERSION 2.8)
project (my-addon)
set(SOURCE_FILES src/main.cc)
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
set_target_properties(${PROJECT_NAME} PROPERTIES
PREFIX ""
SUFFIX ".node"
COMMON_LANGUAGE_RUNTIME "") # "pure" and "safe" unsupported in VS 2017
target_include_directories(${PROJECT_NAME}
PRIVATE ${CMAKE_SOURCE_DIR}/node_modules/node-addon-api
PRIVATE ${CMAKE_JS_INC})
target_link_libraries(${PROJECT_NAME} ${CMAKE_JS_LIB})
从一个package.json
开始
{
"name": "my-addon",
"version": "1.0.0",
"description": "My node.js addon",
"main": "main.js",
"scripts": {
"test": "node main.js",
"install": "cmake-js compile"
}
}
main.js
喜欢
var addon = require('bindings')('my-addon');
console.log("hello: " + addon.doSomething());
一个src/main.cc
喜欢
#include <napi.h>
namespace myaddon
{
#pragma managed
void callManaged()
{
System::String^ result = gcnew System::String("hola");
System::Console::WriteLine("It works: " + result);
}
#pragma unmanaged
Napi::String MyMethod(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
callManaged();
return Napi::String::New(env, "world");
}
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "doSomething"),
Napi::Function::New(env, MyMethod));
return exports;
}
NODE_API_MODULE(myaddon, Init)
}
建造,运行
npm install bindings
npm install node-addon-api
npm install cmake-js
npm install
要执行,运行
npm test