我想在我的 cpp 项目中使用 cpp dll 的函数,所以我在我的代码中包含了 dll 和头文件,我尝试了两种调用函数的方法:
直接使用它的签名,我得到了这个错误:
unresolved external symbol "Connect" that is being referenced in the "main" function.
使用 LoadLibrary 加载 dll 和 GetProcAddress 以指向函数,当我运行时,异常抛出:
Exception thrown at 0x0000000000000000 in MyCode.exe: 0xC0000005: Access violation executing location 0x0000000000000000.
dll的头文件:
#pragma once
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <winsock2.h>
#include <Ws2tcpip.h>
#pragma comment(lib, "Ws2_32.lib")
#define DllExport extern "C" __declspec(dllexport)
SOCKET sock;
WSADATA initialisation_win32;
DllExport int Connect(const char* address, unsigned int timeout);
这就是我试过的:
// 1st way
int a = Connect("192.168.2.10" , 10);
// 2nd way
HINSTANCE hGetProcIDDLL = LoadLibrary(TEXT("MyDll.dll"));
typedef int (*CNCT)(const char* , unsigned int );
CNCT Connect = (CNCT)GetProcAddress(hGetProcIDDLL, "Connect");
const char* adrr = "192.168.2.10";
if (Connect(adrr, 10))
qDebug() << "Card connected";
else
qDebug() << " card disconnected";
FreeLibrary(hGetProcIDDLL);
如果您想将
dll
中的代码直接包含到您的 eveculable 中,您需要将相应的 .lib 文件链接到您的项目中。这告诉链接器如何链接符号。
您不需要 .lib 文件来动态加载 dll。
LoadLibrary
函数确实需要能够找到 dll。你正在加载。
在调用 GetProcAddress 之前,您应该检查 LoadLibrary 的结果并确保它不为空。如果找不到 dll,LoadLibrary 将失败。我认为这正在发生在你的情况下。
带有
__declspec(dllexport)
的方法需要在头文件中进行条件编译。实现 DLL 有一个定义,它控制函数是导入还是导出。
#ifdef IMPLEMENTING_THE_DLL
#define DllAPI extern "C" __declspec(dllexport)
#else
#define DllAPI extern "C" __declspec(dllimport)
#endif
DllAPI int Connect(const char* address, unsigned int timeout);
如果您在消费项目中包含头文件,您将获得导致加载时绑定行为的
__declspec(dllimport)
。
在构建 DLL 项目时,会生成一个导入库 (.LIB)。您必须将此 .LIB 文件添加到使用项目以解决链接器错误中的外部引用。
问题是我的DLL是为x86架构编译的,而我的应用程序是为x64架构编译的,两者不兼容,无法成功加载DLL。 我通过为正确的架构 (x64) 重新编译 DLL 解决了这个问题,然后它成功加载到我的应用程序中。