c++ - 使用 lambda 的 DLL 中未解析的外部符号
问题描述
我有一个 DLL 的以下结构部分:
实用程序.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);
}
实用程序.cpp
#include "Utils.h"
namespace Utils
{
UTILS_API void Foo(MyCustomPriorityQueue & myQueue)
{
// implementation
}
}
这些被构建到一个 DLL 中,然后链接到一个可执行文件中,该可执行文件创建MyCustomPriorityQueue
并调用Foo
.
工具.cpp
#include "Utils.h"
int main()
{
MyCustomPriorityQueue myQueue(MyCustomComparator);
// add things to queue
myQueue.emplace(...)
Utils::Foo(myQueue);
}
这无法unresolved externals
在Foo
API 上构建。关于可能导致这种情况的任何想法?我知道,直到我添加了带有自定义比较器的优先级队列作为导出 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(如果是 win)或readelf(如果是 unix)来检查 dll 的导出符号和客户端的导入符号。
推荐阅读
- email - Google Analytics - 电子邮件跟踪链接点击 - 如何在同一视图中查看所有自定义活动数据(“发送”、“打开”、“点击”)
- python - LSTM,多二进制数组输入和过拟合处理
- php - JQuery 特定问题 - PHP JSON 返回
- python - Python OpenCV VideoCapture read() 无法读取帧
- c - 在 Visual Studio 和 C 项目上运行之间的不一致
- data-mining - 数据挖掘,维度灾难
- testing - 开玩笑未解决的承诺不会失败
- swift - 在 react-native 和 swift 之间共享 cookie
- angular - 角度嵌套模型驱动的反应形式选择选项发布请求不起作用
- java - 如何使用 Android MediaPlayer 播放视频流?FileDescriptor,Uri,Path,MediaDataSource?