¿Se podría escribir una extensión Node.js nativa en Go, en lugar de en C ++?

Eso es todo lo que hay en mi pregunta, realmente, pero creo que es una cosa interesante que hay que responder.

Con la adición de soporte para bibliotecas compartidas en marcha, esto es posible ahora.

archivo: calculator.go

// package name: calculator package main import "C" //export Sum func Sum(x, y float64) float64 { return x + y } func main() { } 

archivo: node-calculator.cc

 #include "calculator.h" #include  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& 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 num = Number::New(isolate, Sum(args[0]->NumberValue(), args[1]->NumberValue())); // Set the return value (using the passed in // FunctionCallbackInfo&) args.GetReturnValue().Set(num); } void init(Local exports) { NODE_SET_METHOD(exports, "add", add); } NODE_MODULE(calculator, init) } 

archivo: test.cc

 const calculator = require('./build/Release/node-calculator'); console.log('4+5=', calculator.add(4, 5)); 

archivo: binding.gyp

 { "targets": [ { "target_name": "node-calculator", "sources": [ "node-calculator.cc" ], "libraries": [ "../calculator.a" ], }, ], } 

Construir:

 go build -buildmode c-archive -o calculator.a calculator.go node-gyp configure node-gyp build 

Salida:

 #> node test.js 4+5= 9 

El módulo nativo para node.js debe interactuar profundamente con el proceso V8 que contiene una gran cantidad de conceptos v8 como gc, javascript context, …

Y no creo que V8 haya expuesto API compatibles y estables para que otros idiomas interactúen con él. Es por eso que el complemento nativo node.js debe comstackrse con C ++ y siempre importa los encabezados V8 C ++.


Pero puede usar GO para escribir los complementos nativos de node.js envolviendo el código GO con C ++:

archivo: module.go

 package main func Add(a, b int) int { return a + b } 

archivo: module.c

 #include  #include  using namespace v8; extern int go_add(int, int) __asm__ ("example.main.Add"); void init(Handle exports) { // call go_add } NODE_MODULE(module, init) 

Más sobre “cómo llamar a GO functionn desde C / C ++”:

Funciones de Call Go de C


Editar:

Consulte los comentarios de @jdi y el enlace: https://groups.google.com/forum/#!msg/golang-nuts/FzPbOwbTlPs/dAJVWQHx6m4J

Cita: Podría ser factible para cosas simples como agregar (que no generan basura o requieren el tiempo de ejecución), pero ninguno de los comstackdores lo admite (por lo que sé). Parte del trabajo se realiza para linux (consulte golang.org/issue/256), pero hay una serie de preguntas abiertas (¿qué sucede cuando carga dos objetos compartidos? Etc.)

Solo para volver a publicar esto como una respuesta en lugar de un comentario …

Seguí con la lista de correo de golang-nuts respecto al soporte para escribir extensiones en Go para otros idiomas. La fuente de la respuesta se puede encontrar aquí .

Podría ser factible para cosas simples como agregar (que no generan basura o requieren el tiempo de ejecución), pero hasta ahora no es compatible con ninguno de los comstackdores. Parte del trabajo se realiza para linux (consulte golang.org/issue/256 ), pero hay una serie de preguntas abiertas (¿qué sucede cuando carga dos objetos compartidos? Etc.)

Entonces, realmente, no parece haber mucho sentido escribir una extensión en Go, sin embargo, ya que la mayoría de las funciones de idioma no estarán disponibles, y de todos modos ya estás en C / C ++ land para agregar la envoltura al punto de entrada .