Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从控制台应用程序动态使用DLL_C++_Windows_Winapi_Dllexport - Fatal编程技术网

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);
    }