Не могу позвонить Ниму dll в NodeJS - PullRequest
0 голосов
/ 04 октября 2018

У меня есть библиотека C clib.c с этой функцией

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

, скомпилированная как:

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

Я использую это в библиотеке Nim под названием '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

Если я вызываю функцию hi2 непосредственно в Nim, она возвращает 900, совершенно точно.Но если я позвоню из NodeJS через FFI:

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

, я получу Segmentation fault (core dumped).

Ответы [ 2 ]

0 голосов
/ 09 февраля 2019

В вашем коде есть две проблемы:

  1. Вы не должны были использовать --noMain.

    Во время инициализации библиотеки nlib.so онабудет загружать символы из clib.so динамически (т.е. с dlopen и dlsym).Указание --noMain мешает этому процессу, и вы должны делать это, только если у вас есть конкретная цель.

  2. Вы должны инициализировать GC Nim при вызове Nim из других языков хоста.

    Обычно это делается по телефону 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
0 голосов
/ 15 октября 2018

Вы не можете использовать FFI одновременно в JS и C. Цитирование из Nim в действии :

Важно отметить, что FFI позволяет вам взаимодействовать сБиблиотеки C, C ++ и Objective-C в одном приложении, но вы не можете одновременно взаимодействовать с библиотеками C и Java-Script.Это потому, что C ++ и Objective-C оба обратно совместимы с C, тогда как JavaScript - это совершенно другой язык.

...