可以在Go中编写一个本地Node.js扩展,而不是C++吗
Could one write a native Node.js extension in Go, as opposed to C++?
这就是我的问题的全部内容,真的,但我认为这是一件有趣的事情。
通过在go中添加对共享库的支持,现在这是可能的。
calculator.go
:
// package name: calculator
package main
import "C"
//export Sum
func Sum(x, y float64) float64 {
return x + y
}
func main() {
}
node-calculator.cc
:
#include "calculator.h"
#include <node.h>
namespace calc {
using v8::FunctionCallbackInfo;
using v8::Isolate;
using v8::Local;
using v8::Object;
using v8::String;
using v8::Value;
using v8::Number;
using v8::Exception;
void add(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
// Check the number of arguments passed.
if (args.Length() < 2) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8(isolate, "Wrong number of arguments")));
return;
}
// Check the argument types
if (!args[0]->IsNumber() || !args[1]->IsNumber()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8(isolate, "Wrong arguments")));
return;
}
// Perform the operation
Local<Number> num = Number::New(isolate, Sum(args[0]->NumberValue(), args[1]->NumberValue()));
// Set the return value (using the passed in
// FunctionCallbackInfo<Value>&)
args.GetReturnValue().Set(num);
}
void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "add", add);
}
NODE_MODULE(calculator, init)
}
binding.gyp
:
{
"targets": [
{
"target_name": "node-calculator",
"sources": [
"node-calculator.cc"
],
"libraries": [
"../calculator.a"
],
},
],
}
test.js
:
const calculator = require('./build/Release/node-calculator');
console.log('4+5=', calculator.add(4, 5));
构建:
go build -buildmode c-archive -o calculator.a calculator.go
node-gyp configure
node-gyp build
输出:
#> node test.js
4+5= 9
node.js的原生模块必须与V8进程深度交互,V8进程包含许多V8概念,如gc、javascript上下文。。。
我认为V8没有为其他语言提供兼容和稳定的API来与之交互。这就是为什么node.js原生插件应该使用C++构建,并且总是导入V8 C++头。
但是您可以使用GO来编写node.js原生插件,方法是用C++包装GO代码:
文件:module.go
package main
func Add(a, b int) int {
return a + b
}
文件:module.c
#include <node.h>
#include <v8.h>
using namespace v8;
extern int go_add(int, int) __asm__ ("example.main.Add");
void init(Handle<Object> exports) {
// call go_add
}
NODE_MODULE(module, init)
关于"如何从C/C++调用GO函数"的更多信息:
从C 调用Go函数
编辑:
请查看@jdi评论和链接:https://groups.google.com/forum/#!msg/golang nuts/FzPbOwbTlPs/dAJVWQHx6m4J
引用:它可能适用于添加之类的简单操作(不生成垃圾或需要运行时),但据我所知,这两个编译器都不支持它。部分工作是针对linux完成的(请参阅golang.org/issue/256),但还有许多悬而未决的问题(当加载两个共享对象时会发生什么?等等)
只是将其作为答案而不是注释转发。。。
我随后收到了golang nuts邮件列表,内容涉及支持在Go中为其他语言编写扩展。响应的来源可以在这里找到。
这可能适用于简单的事情,如添加(不会生成垃圾或需要运行时),但据我所知,要么是编译器。部分工作是为linux完成的(见golang.org/issue/256),但还有许多悬而未决的问题(当你加载两个共享对象时会发生什么?等等)
所以,实际上,在Go中编写扩展似乎没有什么意义,因为大多数语言功能都不可用,而且无论如何,您已经在C/C++领域为入口点添加包装器了。
- 是否可以通过C++扩展强制多个python进程共享同一内存
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 扩展光电二极管探测器以支持多个传感器
- JS相等运算符(如===)是否可以使用embind类型
- C++中的VLA,扩展名为std=C++11
- OpenGL 和 GLM 矩阵无法正确扩展,总是按比例缩小
- 基于范围的 for 循环:迭代使用一个元素扩展的向量
- C++返回 Numpy 数组的 Python 扩展模块
- 扩展可变参数模板中的变量名称
- 扩展C++生成的代码的模板参数类型名称
- 我想通过带有C++和Python的插件创建一个可扩展的应用程序
- 可以在Go中编写一个本地Node.js扩展,而不是C++吗
- .net 本机扩展名 Node.js.
- 从 C++ 节点调用 JavaScript 函数.js扩展
- 从Asm.js/emscripten启用WebGL扩展
- js-bson:无法加载c++bson扩展,使用纯js版本(Openshift-nodejs)
- 我可以将 Node.js C++ 扩展与 Node 的内部 OpenSSL 实现链接吗?
- Node.js 的本机 c++ 扩展:"cloning"构造函数中的本地<值>
- Node.js C++将多个CC文件扩展为一个模块