如何在 Windows 上使用带有 node-gyp 的静态库?

How to use a static library with node-gyp on Windows?

我正在尝试 link 使用 node-gyp 的静态库,以便将其用作本机 node 插件。但是,当我 运行 node-gyp rebuild 我得到以下 linking 错误:

error LNK2001: unresolved external symbol "double __cdecl mylibengine::criticalZvalue(double)" (?criticalZvalue@mylibengine@@YANN@Z)

紧随其后的是:

C:\Users\Mihai\Desktop\msp-addon\build\Release\mylib-addon.node : fatal error LNK1120: 1 unresolved externals [C:\Users\Mihai\Desktop\mylib-addon\build\mylib-addon.vcxproj

binding.gyp 看起来像:

{
    'targets': [{
        'target_name': 'mylib-addon',
        'cflags!': [ '-fno-exceptions' ],
        'cflags_cc!': [ '-fno-exceptions' ],

        'include_dirs': [
            '<!@(node -p \"require(\'node-addon-api\').include\")',
            '<(module_root_dir)/dependencies/mylib/include/'
        ],

        'sources': [
            'src/MyLibNode.cpp'
        ],

        'dependencies': [
            '<!(node -p \"require(\'node-addon-api\').gyp\")'
        ],

        'libraries': [
            '<(module_root_dir)/dependencies/mylib/lib/x64/libmylib.a'
        ],

        'defines': [ 'NAPI_DISABLE_CPP_EXCEPTIONS' ]
    }]
}

MyLibNode.cpp 看起来像这样:

#include <napi.h>
#include "engine.h"

Napi::Object InitAll(Napi::Env env, Napi::Object exports)
{
    // Temporary check to make sure `libmylib.a` works.
    mylibengine::criticalZvalue(.3);

    return exports;
}

NODE_API_MODULE(mspaddon, InitAll)

我确信 linker 可以找到 libmylib.a,因为当我更改库的名称(例如,更改为 disabled.a)时,我得到一个不同的错误提示无法打开输入文件。但是,无法解析外部符号

我发现了一个类似的、未回答的问题 here。其他问题的答案表明将完整的库路径添加到 libraries,但我认为这不是我的场景的问题。

为什么node-gyp无法解析外部符号?


附加信息:

我有以下项目结构:

├───build
└───dependencies
    └───mylib
        ├───include
        └───lib
            └───x64
#pragma once

namespace mylibengine
{
    double criticalZvalue(double quantile);
}
#include <iostream>
#include <engine.h>


int main()
{
    std::cout << "Main working." << "\n";
    std::cout << mylibengine::criticalZvalue(.3) << "\n";
}

我可以 link 可执行文件中的库为:

g++ -obuild/main main.cpp -Idependencies/mylib/include/ -Ldependencies/mylib/lib/x64/ -lmylib

此时运行ning main.exe会输出就好了:

Main working.
-0.524002

在上面的问题中,静态库 libmylib.a 是使用 mingw64 安装的 g++ 编译的。但是,node-gyp 使用 Microsoft C 和 C++ (MSVC) 运行时库。

node-gyp 似乎不支持 mingw64(即参见 this issue on GitHub)。在链接的问题中,有人指出

mingw uses its own name mangling scheme that makes interoperability impossible.

这也是本题遇到的问题(即error LNK2001: unresolved external symbol)。解决方案是使用 Microsoft 工具链创建静态库,然后链接器将正确解析符号。