You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用require导入Node.js .node插件失败问题求助

Node.js Addon 加载失败问题排查与解决

问题详情

使用node-addon-api和node-gyp 9.3.1开发Node.js插件时,执行require导入出现以下错误:

Uncaught Error: The specified module could not be found.
\\?\C:\Users\simon\Documents\draw2d\build\Release\canvas_sdl2.node
    at Module._extensions..node (node:internal/modules/cjs/loader:1353:18)
    at Module.load (node:internal/modules/cjs/loader:1125:32)
    at Module._load (node:internal/modules/cjs/loader:965:12)
    at Module.require (node:internal/modules/cjs/loader:1149:19)
    at require (node:internal/modules/helpers:121:18) {
  code: 'ERR_DLOPEN_FAILED'
}

使用的Node.js版本为v20.0.0,也曾尝试v18.16.0。

插件代码

#include <napi.h>
#include <SDL.h>
#include <string>

Napi::Value sdl_init_n(const Napi::CallbackInfo& info)
{
    Napi::Env env = info.Env();
    Uint32 flags = info[0].As<Napi::Number>().Uint32Value();
    return Napi::Number::New(env, SDL_Init(flags));
}

Napi::Object Init(Napi::Env env, Napi::Object exports)
{
    exports.Set(Napi::String::New(env, "init"), Napi::Function::New<sdl_init_n>(env));
    //exports.Set(Napi::String::New(env, "createWindow"), Napi::Function::New<sdl_create_window>(env));
    return exports;
}

NODE_API_MODULE(addon, Init);

binding.gyp配置

{
    'targets': [
        {
            'target_name': 'canvas_sdl2',
            'sources': ['src\\sdl2node.cpp'],
            'include_dirs': [
                "C:\\SDL\\SDL2-2.26.5\\include",
                "C:\\SDL_Image\\SDL2_image-2.6.3\\include",
                "<!@(node -p \"require('node-addon-api').include\")"
            ],
            'dependencies': [
                "<!(node -p \"require('node-addon-api').gyp\")"
            ],
            'libraries': [
                "C:\\SDL\\SDL2-2.26.5\\lib\\x64\\SDL2.lib",
                "C:\\SDL_Image\\SDL2_image-2.6.3\\lib\\x64\\SDL2_image.lib"
            ],
            'cflags!': ['-fno-exceptions'],
            'cflags_cc!': ['-fno-exceptions'],
            'xcode_settings': {
                'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
                'CLANG_CXX_LIBRARY': 'libc++',
                'MACOSX_DEPLOYMENT_TARGET': '10.7'
            },
            'msvs_settings': {
                'VCCLCompilerTool': {'ExceptionHandling': 1},
            }
        }
    ]
}

已尝试的操作

  • 将NODE_API_MODULE(addon, Init)修改为NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)
  • 移除require语句中的.node扩展名

解决思路与方案

1. 补充SDL运行时动态库

Windows平台下,编译时链接的SDL2.lib和SDL2_image.lib是导入库,运行时需要对应的动态链接库(.dll)才能加载插件:

  • 从C:\SDL\SDL2-2.26.5\lib\x64复制SDL2.dll
  • 从C:\SDL_Image\SDL2_image-2.6.3\lib\x64复制SDL2_image.dll
  • 将上述文件粘贴到插件所在的build/Release目录,或者添加所在路径到系统PATH环境变量

2. 确认架构匹配

确保Node.js版本与SDL库的编译架构一致:

  • 执行node -p process.arch查看Node.js架构(应为x64)
  • 确认使用的SDL库是x64版本(与binding.gyp中配置的路径一致)
  • 重新执行node-gyp clean rebuild,确保编译过程无架构不兼容报错

3. 验证模块名称一致性

使用NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)是正确的,该宏会自动匹配binding.gyp中target_name(即canvas_sdl2),确保编译生成的模块名称与导入时的名称一致。

4. 检查SDL_image的依赖库

SDL_image通常依赖第三方图像解码库(如libpng16-16.dll、jpeg62.dll等),如果使用预编译的SDL_image包,需将这些依赖的.dll文件一并复制到build/Release目录。

5. 重新编译并验证文件完整性

  • 执行node-gyp clean清理旧编译文件
  • 执行node-gyp configure --release和node-gyp build重新编译
  • 确认build/Release/canvas_sdl2.node文件存在且大小正常,无编译错误输出

内容的提问来源于stack exchange,提问作者Simone Ancona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 16:53:16