SWIG for JavaScript: «Модуль не зарегистрировался самостоятельно».в процессе - PullRequest
0 голосов
/ 29 ноября 2018

С помощью SWIG 3.0.12 и узла 8.12.0 я хочу создать собственный модуль из некоторой минимальной базы кода:

api.h:

#pragma once
#include <string>
std::string foo();

api.cpp:

#include "api.h"
std::string foo() {
  return "hello world";
}

api.i:

%module(directors="1") api
%{
#include <api.h>
%}
%include "api.h"

для сборки запускаемого мной узла-модуля:

swig -c++ -javascript -node api.i
g++ -c -fPIC api_wrap.cxx api.cpp  -I /usr/include/node -I .
g++ -shared *.o -o api.node   

.. и попробуйте импортировать его:

node -e "api = require('./api.node');"

Но теперь я получаю

module.js:682
  return process.dlopen(module, path._makeLong(filename));
                 ^

Error: Module did not self-register.
    at Object.Module._extensions..node (module.js:682:18)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at [eval]:1:7
    at ContextifyScript.Script.runInThisContext (vm.js:50:33)
    at Object.runInThisContext (vm.js:139:38)
    at Object.<anonymous> ([eval]-wrapper:6:22)

Я нашел много вопросов и ответов относительно подобных ошибок, но все онипохоже, что оно связано с npm и неправильными версиями узловых модулей и средой выполнения узлов.

Что я делаю не так?

1 Ответ

0 голосов
/ 04 декабря 2018

К сожалению, текущий выпуск swig (3.0.12) не поддерживает Node.js версии 7 или новее.Вместо этого вы получаете ошибки времени компиляции, такие как error: no template named 'WeakCallbackData' in namespace 'v8'

Чтобы использовать swig с Узлом 8, либо используйте основную ветвь, более позднюю версию swig (похоже, это будет исправлено вследующий выпуск, который, вероятно, будет 3.0.13), или загрузите 4 файла, измененные в PR 968 , и установите их вместо тех, которые поставлялись с swig 3.0.12.На моем Mac эти файлы находятся в /usr/local/Cellar/swig/3.0.12/share/swig/3.0.12/javascript/v8/

После этого, тем не менее, @frans еще есть над чем поработать.

Согласно документации SWIG , "крайне важно скомпилировать ваш модуль, используя те же флаги компилятора, которые использовались для сборки v8 ", для чего они рекомендуют собирать ваш модуль с node-gyp.

. Вам необходимо создать binding.gyp, например:

{
  "targets": [
    {
      "target_name": "api",
      "sources": [ "api.cpp", "api_wrap.cxx" ]
    }
  ]
}

, а затем, после создания оболочки с swig, соберите модуль с

 node-gyp configure build

(При необходимости установите node-gyp с npm install -g node-gyp)

Вы, вероятно, также не хотите %module(directors="1") для JavaScript, и вы не должны использовать стиль скобок include <file.h> для своих собственных заголовочных файлов.

Кроме того, если вы хотите использовать std::string, вам необходимо включить std_string.i в файл интерфейса.

Я полагаю, ваш api.i будет лучше как

%module api
%{
#include "api.h"
%}

%include "std_string.i"
%include "api.h"

Наконец, когда вы закончите, модуль будет в ./build/Release, так что тестируйте с

node -e "api = require('./build/Release/api.node'); console.log(api.foo());"
...