代码之家  ›  专栏  ›  技术社区  ›  frans

JavaScript的SWIG:“模块未自注册。”正在加载

  •  0
  • frans  · 技术社区  · 7 年前

    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 回复  |  直到 7 年前
        1
  •  2
  •   Old Pro    7 年前

    不幸的是,当前发布的 swig (3.0.12)不支持Node.js版本7或更高版本。相反,会出现编译时错误,如 error: no template named 'WeakCallbackData' in namespace 'v8'

    大口 对于节点8,可以使用主分支(更高版本的 大口 (看起来这将在下一版本(可能是3.0.13)中修复),或者下载在中更改的4个文件 PR 968 并将其安装在随附的位置 swig 3.0.12 /usr/local/Cellar/swig/3.0.12/share/swig/3.0.12/javascript/v8/

    根据 SWIG documentation ,“使用与构建v8相同的编译器标志编译模块是至关重要的”,为此,他们建议使用 node-gyp

    您需要创建一个 binding.gyp 这样地:

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

    然后,在使用 大口

     node-gyp configure build
    

    (如有必要,安装 节点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());"