首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >可以用Go写一个原生的Node.js扩展,而不是C++吗?

可以用Go写一个原生的Node.js扩展,而不是C++吗?
EN

Stack Overflow用户
提问于 2013-12-22 18:07:54
回答 3查看 6.9K关注 0票数 27

这就是我所有的问题,真的,但我认为这是一件有趣的事情。

EN

回答 3

Stack Overflow用户

发布于 2016-09-01 12:16:41

随着在go中添加对共享库的支持,这一点现在成为可能。

calculator.go

代码语言:javascript
代码运行次数:0
运行
复制
// package name: calculator
package main

import "C"

//export Sum
func Sum(x, y float64) float64 {
    return x + y
}

func main() {
}

node-calculator.cc

代码语言:javascript
代码运行次数:0
运行
复制
#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

代码语言:javascript
代码运行次数:0
运行
复制
{
  "targets": [
    {
      "target_name": "node-calculator",
      "sources": [
        "node-calculator.cc"
      ],
      "libraries": [
        "../calculator.a"
      ],
    },
  ],
}

test.js

代码语言:javascript
代码运行次数:0
运行
复制
const calculator = require('./build/Release/node-calculator');
console.log('4+5=', calculator.add(4, 5));

内部版本:

代码语言:javascript
代码运行次数:0
运行
复制
go build -buildmode c-archive -o calculator.a calculator.go
node-gyp configure
node-gyp build

输出:

代码语言:javascript
代码运行次数:0
运行
复制
#> node test.js 
4+5= 9
票数 16
EN

Stack Overflow用户

发布于 2013-12-22 19:27:59

node.js的原生模块必须与包含大量V8概念的v8流程进行深度交互,如gc、javascript上下文、...

而且我不认为V8已经为其他语言提供了兼容和稳定的API来与之交互。这就是为什么应该用C++构建node.js原生插件,并且总是导入V8 C++头。

但是您可以使用GO通过将GO代码包装在C++中来编写node.js原生插件:

文件: module.go

代码语言:javascript
代码运行次数:0
运行
复制
package main

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

文件: module.c

代码语言:javascript
代码运行次数:0
运行
复制
#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)

有关"how to call GO functionn from C/C++“的更多信息:

Call Go functions from C

编辑:

请查看@jdi评论和链接:https://groups.google.com/forum/#!msg/golang-nuts/FzPbOwbTlPs/dAJVWQHx6m4J

引用:对于像add这样的简单事情,它可能是可行的(不会生成垃圾或需要运行时),但据我所知,这两个编译器都还不支持它。部分工作是针对linux完成的(请参阅golang.org/issue/256),但仍有许多悬而未决的问题(加载两个共享对象时会发生什么?等)

票数 11
EN

Stack Overflow用户

发布于 2014-01-04 11:04:52

只是想把这篇文章作为回复而不是评论来转发。

我随后查看了golang-nuts邮件列表,了解对其他语言的Go扩展的支持。响应can be found here的源。

它对于像add这样的简单事情可能是可行的(不会生成垃圾或需要运行时),但据我所知,这两个编译器都还不支持它。部分工作是针对linux完成的(请参阅golang.org/issue/256),但仍有许多悬而未决的问题(加载两个共享对象时会发生什么?等)

因此,实际上,在Go中编写扩展似乎没有多大意义,因为大多数语言特性都不可用,而且您已经在C/C++领域中为入口点添加了包装器。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20728255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档