微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用Lambda的DLL中无法解析的外部符号

如何解决使用Lambda的DLL中无法解析的外部符号

我具有DLL的以下结构部分:

Utils.h

#ifdef _EXPORTS
#    define UTILS_API __declspec(dllexport)
#else
#    define UTILS_API __declspec(dllimport)
#endif

namespace Utils
{
    static auto MyCustomComparator = [](std::shared_ptr<IMyType>& o1,std::shared_ptr<IMyType>& o2) {
        // do some stuff and compare o1 and o2
    };

    using MyCustomPriorityQueue = std::priority_queue<std::shared_ptr<IMyType>,std::vector<std::shared_ptr<IMyType>>,decltype(MyCustomComparator)>;

    UTILS_API void Foo(MyCustomPriorityQueue& myQueue);
}

Utils.cpp

#include "Utils.h"

namespace Utils
{
    UTILS_API void Foo(MyCustomPriorityQueue & myQueue)
    {
        // implementation
    }
}

将这些文件内置到DLL中,然后将其链接到可执行文件中,该可执行文件将创建MyCustomPriorityQueue调用Foo

Tool.cpp

#include "Utils.h"

int main()
{
    MyCustomPriorityQueue myQueue(MyCustomComparator);

    // add things to queue
    myQueue.emplace(...)

    Utils::Foo(myQueue);
}

无法在unresolved externals API上使用Foo构建。关于什么可能导致此的任何想法?我知道,直到我将优先级队列与自定义比较器一起作为导出的API的一部分(它曾经在Foo的内部)添加到一起,所有这些工作之后,因此在链接和确定类型时肯定出了问题自定义优先级队列的内容

error LNK2001: unresolved external symbol "__declspec(dllimport) void __cdecl Utils::Foo(struct class std::priority_queue<class std::shared_ptr<class Utils::IMyType>,class std::vector<class std::shared_ptr<class Utils::IMyType>,class std::allocator<class std::shared_ptr<class Utils::IMyType> > >,class <lambda_19161500ece6d0a8a5b52705767e713b> const > &)" (__imp_?Foo@Utils@@$priority_queue@V?$shared_ptr@VIMyType@Utils@@@std@@V?$vector@V?$shared_ptr@VIMyType@Utils@@@std@@V?$allocator@V?$shared_ptr@VIMyType@Utils@@@std@@@2@@2@$$CBV<lambda_19161500ece6d0a8a5b52705767e713b>@@@std@@@Z)
bin\Tool.exe : Fatal error LNK1120: 1 unresolved externals

解决方法

您必须确保: 通过创建DLL,应定义_EXPORTS宏 。 在使用DLL的客户端代码中,不应定义_EXPORTS

还请注意有关 lambda 的信息:包括相同头文件的2个编译单元将看到不同的lambda类型,因为每个lambda都有不同的类型。例如,在此示例代码中:

auto a = []() {};
auto b = []() {};

类型a和b将不同。

我认为您无法在自己的情况下使用lambda。只需声明常规类型即可。

根据编译平台的不同,可以使用 dumpbin (如果获胜)或 readelf (如果为unix)来检查dll的导出符号并为导入符号客户。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。