"The specified module could not be found" 使用自定义 nodejs 插件时

"The specified module could not be found" when using a custom nodejs addon

我正在编写一个依赖于 OpenGL 的 nodejs 插件 (glfw)。它编译成功但是当我尝试在节点中使用它时出现错误 The specified module could not be found.

这是插件 C++ 代码中有问题的部分:

#include <glfw/glfw3.h>

if(glfwInit()) {
    printf("glfw init success");
}
else {
    printf("glfw init failed");
}

在插件中使用这个,它编译但导致节点错误。没有这个它编译和运行没有问题。

这是我的 binding.gyp:

{
  "targets": [
    {
      "target_name": "engine",
      "sources": [
        "addon/addon.cc"
      ],
      "libraries": [
            "<(module_root_dir)/addon/lib/gl/glfw3dll.lib"
        ],
      "include_dirs": [
        "addon/lib",
        "<!@(node -p \"require('node-addon-api').include\")"
      ],
      'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
    }
  ]
}

和插件文件结构:

addon
  lib
    glfw
      glfw3.dll
      glfw3.h
      glfw3.lib
      glfw3dll.lib
      glfw3native.h
      opengl32.lib
  addon.cc

编辑: 新 binding.gyp:

{
  "targets": [
    {
      "target_name": "engine",
      "sources": [
        "addon/addon.cc"
      ],
      "libraries": [
        "-lglfw3dll",
        "-lopengl32",
        "-L<module_root_dir)/lib/glfw",
        "-Wl,-rpath,$$ORIGIN/../../lib",
        ],
      "include_dirs": [
        "addon/lib",
        '<!@(node -p "require(\'node-addon-api\').include")'
      ],
      'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ],
    }
  ]
}

我不确定这是你的问题,但说服加载器加载本地目录中的特定库可能有点棘手。我将此部分添加到 binding.gyp 中的 targets 数组。

诀窍是告诉链接器查找相对于 $ORIGIN(插件所在的位置)的库。因为插件在 build/Release 中,所以 $ORIGINbuild/Release 并且 ../../ 让你回到模块根目录。

只是经过反复试验才找到通过 binding.gyp 和链接器的引用规则指定 $ORIGIN 的正确方法。 $$ORIGIN 导致 $ORIGIN 被嵌入到节点插件中。

'conditions': [
    ['OS in "linux"', {
    # includes reference glfw3dll/glfw3dll.h, so
    'include_dirs': [
      '<!@(node -p "require(\'node-addon-api\').include")',
        '<(module_root_dir)/'
    ],
    'libraries': [
        '-lglfw3dll',
        '-L<(module_root_dir)/dir-for-glfw3dll/',
        '-Wl,-rpath-link,<(module_root_dir)/dir-for-glfw3dll/',
        '-Wl,-rpath,$$ORIGIN/../../dir-for-glfw3dll/'
    ],
    }]
]

(我把我的文件名改成了你的文件,放在module_root_dir下的一个目录下。)

我设法让它与这个 binding.gyp 文件一起工作:

{
  "targets": [
    {
      "target_name": "engine",
      "sources": [
        "addon/addon.cc"
      ],
      "libraries": [
        "legacy_stdio_definitions.lib",
        "msvcrt.lib",
        "msvcmrt.lib",
        "<(module_root_dir)/addon/lib/glfw/opengl32.lib",
        "<(module_root_dir)/addon/lib/glfw/glfw3.lib"
        ],
      "include_dirs": [
        "addon/lib",
        '<!@(node -p "require(\'node-addon-api\').include")',
      ],
      'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ]
    }
  ]
}

以防其他人遇到同样的问题并最终出现在这里。插件所需的库需要在运行时可以访问,即使链接器设法找到它也是如此。

例如,如果这是在 Windows 上,并且您在 build/link 期间与 foo.lib 链接,在运行时,foo.dll 应该在同一文件夹中(对我来说,它在与 .node 相同的文件夹中工作)或在路径中的文件夹中工作。否则它不会被加载并且会抛出这个错误。我认为是非常无法解释的错误。

此外,将库保存在与 .node 相同的文件夹中有助于隔离不同的架构构建和依赖项(x86、x64 等)。