0

我正在编写一个依赖于 OpenGL ( glfw) 的 nodejs 插件。它编译成功,但是当我尝试在节点中使用它时,我得到了错误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' ],
    }
  ]
}
4

3 回答 3

1

我设法让它与这个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' ]
    }
  ]
}
于 2019-12-08T19:50:52.980 回答
1

以防万一其他人有同样的问题并在这里结束。插件所需的库需要在运行时触手可及,即使链接器设法找到它。

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

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

于 2021-02-10T01:35:05.023 回答
0

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

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

只是通过反复试验找到正确的方法来指定$ORIGINviabinding.gyp和链接器的引用规则。\$$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下的一个目录下。)

于 2019-12-02T16:15:39.037 回答