C++ 从控制台应用程序动态使用DLL
我正在尝试创建一个库C++ 从控制台应用程序动态使用DLL,c++,windows,winapi,dllexport,C++,Windows,Winapi,Dllexport,我正在尝试创建一个库Lib.dll,以便从控制台应用程序中动态调用,但找不到要调用的函数funci() Lib.dll是在Visual Studio 2019中创建的项目(控制台应用程序,但设置为配置类型:.dll)的结果 Lib.cpp是该项目中唯一的文件,仅包含以下代码: __declspec(dllexport) int funci() { return 50; } 我认为我正确地导出了函数,因为我通过使用找到了函数 但是,我很难通过控制台应用程序(.exe)找到该函数: #
Lib.dll
,以便从控制台应用程序中动态调用,但找不到要调用的函数funci()
Lib.dll
是在Visual Studio 2019中创建的项目(控制台应用程序,但设置为配置类型:.dll)的结果
Lib.cpp
是该项目中唯一的文件,仅包含以下代码:
__declspec(dllexport) int funci()
{
return 50;
}
我认为我正确地导出了函数,因为我通过使用找到了函数
但是,我很难通过控制台应用程序(.exe)找到该函数:
#包括
#包括
typedef int(uu cdecl*o_funci)(无效);
o_funci funci;
int main()
{
HINSTANCE hGetProcIDDLL=LoadLibraryA(“C:\\Lib.dll”);
如果(!hGetProcIDDLL){
std::cout您正在使用的工具正在向您显示一个非常精确的导出名称版本。它的真实名称将包括名称篡改,这是一种复杂的尝试,试图将调用信息嵌入导出名称中
使用GetProcAddress
,您有许多选项可以实现这一点:
使用真实的导出名称。您的工具可能可以选择查看未修饰的名称(损坏的导出名称)
使用模块定义文件(*.def)导出函数,您甚至可以在其中指定将导出为的名称
按序号而不是名称导入
将函数包装在extern“C”{…}
中,该函数将使用C样式命名,从而避免名称混乱
最常见的解决方案可能是#4,而#2是紧随其后的第二个。WTF?我错过了extern“C”
,但看了OP的快照后想:嗯。\uuCDECL
可能会修复它,但我没有经验。我从未想到DLL导出查看器显示了导出名称的一个非常固定的版本(我有一些经验,但我不记得它是怎么做的。)多么卑鄙……“Scheff”我有一些经验,但我不记得它是怎么做的。“Dependecy Walker有一个拨号名为“un装饰C++函数”。我不确定这是否可以被配置(或被记住),但在我的情况下,“真”(装饰)名称默认显示。这就是我所认为的“欠下手”。(沃克仍然摇滚)。
无法避免名称损坏。它只是选择了一组不同的名称修饰,更易于阅读和键入。还有第五个选项:编译64位二进制文件(使用外部“C”
)。在这种情况下,名称修饰将消失。@jub:按顺序导入要求您永远不要更改导出顺序。这是一个非常难满足的要求,如果您只需要更方便的重要名称,则很难证明这一点。
#include <windows.h>
#include <iostream>
typedef int(__cdecl* o_funci)(void);
o_funci funci;
int main()
{
HINSTANCE hGetProcIDDLL = LoadLibraryA("C:\\Lib.dll");
if (!hGetProcIDDLL) {
std::cout << "could not load the dynamic library" << std::endl;
return EXIT_FAILURE;
}
// resolve function address here
funci = (o_funci) GetProcAddress(hGetProcIDDLL, "funci");
if (!funci) {
std::cout << "could not locate the function" << std::endl;
return EXIT_FAILURE;
}
std::cout << "funci() returned " << funci() << std::endl;
FreeLibrary(hGetProcIDDLL);
}