使用 lambda 的 DLL 中未解析的外部符号
Unresolved External Symbols in DLL using lambda
我有以下 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);
}
这无法在 Foo
API 上使用 unresolved externals
构建。关于什么可能导致这种情况的任何想法?我知道,直到我添加带有自定义比较器的优先级队列作为导出的 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 的导出符号并为客户端导入符号。
我有以下 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);
}
这无法在 Foo
API 上使用 unresolved externals
构建。关于什么可能导致这种情况的任何想法?我知道,直到我添加带有自定义比较器的优先级队列作为导出的 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 的导出符号并为客户端导入符号。