无法在NodeJS中调用Nim dll

时间:2018-10-04 10:09:34

标签: node.js ffi nim

我有一个具有此功能的C库clib.c

int hi(char* hello) { return 900; }

编译为:

gcc clib.c -o clib.so --shared -fPIC

我正在Nim libray中使用它,名为'nlib.nim`:

proc hi*(hello: cstring): cint {.cdecl, importc: "hi", dynlib: "./clib.so".}
proc hi2*(hello: cstring): cint {.cdecl, exportc.} = return hi(hello)

表示为:

nim c --app:lib --noMain -o:nlib.so nlib.nim

如果我直接在Nim中调用hi2函数,它将完美返回900。但是,如果我通过FFI从NodeJS调用它:

var ffi = require('ffi');
var lib = ffi.Library('./nlib.so', { 'hi2' : [ "int", ["string"] ] });
console.log(lib.hi2("hey"));

我得到一个Segmentation fault (core dumped)

2 个答案:

答案 0 :(得分:1)

您的代码中有两个问题:

  1. 您不应该使用--noMain

    nlib.so库初始化期间,它将动态地(即使用clib.sodlopen加载dlsym中的符号。指定--noMain会干扰此过程,只有在您有特定目标时才应这样做。

  2. 从其他宿主语言调用Nim时,应初始化Nim GC。

    通常通过调用setupForeignThreadGc来完成。要使其可用,您应该使用--threads:on进行编译。

因此,最终的解决方案如下所示:

# nlib.nim

proc hi*(hello: cstring): cint {.cdecl, importc: "hi", dynlib: "./clib.so".}

proc nlib_init* {.cdecl, exportc.} =
  setupForeignThreadGc()

proc nlib_hi*(hello: cstring): cint {.cdecl, exportc.} =
  return hi(hello)

编译为:

nim c --threads:on --app:lib -o:nlib.so nlib.nim

然后在node.js中,我们有:

# nlib.js

var ffi = require('ffi');

var nlib = ffi.Library('./nlib.so', {
  'nlib_init': [ "void", []],
  'nlib_hi': [ "int", ["string"] ]
});

nlib.nlib_init()
console.log(nlib.nlib_hi("hey"));

执行:

node nlib.js

输出:

900

答案 1 :(得分:0)

您不能在JS和C中同时使用FFI。 引用Nim in Action

  

请务必注意,FFI允许您与C进行接口,   C ++和Objective-C库位于同一应用程序中,但您不能   同时与C和Java Script库交互。这个   因为C ++和Objective-C都向后兼容C,   而JavaScript是一种完全不同的语言。

相关问题