【问题标题】:How to use a static library with node-gyp on Windows?如何在 Windows 上使用带有 node-gyp 的静态库?
【发布时间】:2019-02-11 14:28:47
【问题描述】:

我正在尝试使用 node-gyp 链接静态库,以便将其用作本机 node 插件。但是,当我运行 node-gyp rebuild 时,出现以下链接错误:

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)

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

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

为什么node-gyp不能解析外部符号?


其他信息:

  • 我正在运行 Windows 10
  • 我通过尝试将其与 g++ 一起使用来测试该库是否可以正常工作,如下所述

我的项目结构如下:

├───build
└───dependencies
    └───mylib
        ├───include
        └───lib
            └───x64
  • dependencies/mylib/include 内我有一个名为engine.h 的头文件,其中包含:
#pragma once

namespace mylibengine
{
    double criticalZvalue(double quantile);
}
  • dependencies/mylib/lib/x64 内我有一个名为libmylib.a 的静态库
  • 在根目录中,我有一个名为main.cpp 的文件,其中包含:
#include <iostream>
#include <engine.h>


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

我可以将可执行文件中的库链接为:

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

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

Main working.
-0.524002

【问题讨论】:

  • 由于您的MyLibNode.cpp 仅调用double mylibengine::criticalZvalue(double),它不能对未定义的引用负责:double mspengine::criticalZvalue(double)。看来您发布的代码(其中没有出现mspengine)并不是实际错误的代码。
  • mspengine 命名空间感到抱歉。错误是LNK2001: unresolved external symbol "double __cdecl mylibengine::criticalZvalue(double)。我将更新问题以反映这一点。
  • @Mihai 我知道这是一个老问题,但是这个问题有什么进展吗?
  • @simon_tulia,请参阅下面的答案。希望对您有所帮助。

标签: c++ node.js linker node-modules node-gyp


【解决方案1】:

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

看起来(例如,参见this issue on GitHubnode-gyp 不支持mingw64。在链接的问题中,有人指出

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

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

【讨论】:

    猜你喜欢
    • 2012-12-29
    • 2013-09-15
    • 2014-02-07
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-04
    • 2016-05-19
    相关资源
    最近更新 更多