C++ GetProcAddress() 找不到静态类的方法

标签 c++ dll dllexport dynamic-loading getprocaddress

我需要在 C++ 中动态加载一个 dll。

我已遵循本教程 http://msdn.microsoft.com/en-us/library/ms235636.aspx创建 dll,一切正常。

然后我关注了这个http://msdn.microsoft.com/en-us/library/64tkc9y5.aspx并且我对控制台应用程序进行了如下调整:

typedef DOUBLE(CALLBACK* DllFunc)(DOUBLE, DOUBLE);

int _tmain(int argc, _TCHAR* argv[])
{
    HINSTANCE hDLL;               // Handle to DLL
    DllFunc dllFunc1;
    DOUBLE p1 = 1.0, p2 = 2.0, r;
    hDLL = LoadLibrary(L"MathFuncsDLL");
    if (hDLL != NULL)
    {
        cout <<  "DLL loaded: " << hDLL << endl;
        dllFunc1 = (DllFunc)GetProcAddress(hDLL, "MyMathFuncs@MathFuncs@Multiply");
        if (!dllFunc1)
        {
            // handle the error
            FreeLibrary(hDLL);
            cout << "Function not found!" << endl;
            return -1;
        }
        else
        {
            // call the function
            r = dllFunc1(p1, p2);
            cout << "The result is: " << r << endl;
        }               
    }
    else {
        cout << "Dll not found" << endl;
        return -1;
    }
    cout << "Press any key to exit." << endl;
    int i;
    cin >> i;
    return 0;
}

DLL 已正确加载且不为空。问题是始终返回 0 的 GetProcAddress() 函数。

我已经尝试过命名空间、类名、方法名的每种组合。我尝试在函数名称中使用作用域运算符 (::) 而不是 @。

我试图将整个命名空间定义为 外部“C” 但没有任何改变。每次我运行或调试控制台应用程序时,它都找不到“乘法”函数。

我想我错过了什么...... 我哪里错了?


编辑

Dependency Walker 向我展示了以下导出表:

DLL Export table

现在我想知道函数名称的最后一部分是什么意思... 为什么 __declspec(dllexports) 添加这些符号?

最佳答案

欢迎使用 C++ 名称修改。编译器添加到您的函数名称中的所有内容都是为了确保每个具有唯一签名的函数都有一个唯一的名称。 Microsoft 以一种方式进行名称重整,而 GCC/Clang 以另一种方式进行。它不是标准化的,但特定操作系统上的编译器都以相同的方式进行名称修改,因此它们都可以相处。

确保您的名字仍可被人类预测的唯一方法是将导出的 DLL 函数声明为 extern "C"。但是,这会限制您导出 C 函数。

在我处理过的库中,有一个导出的 C 函数用于初始化库并取回接口(interface)指针。在这种情况下,“接口(interface)”是指没有数据和只有虚函数的抽象虚基类。

这是声明接口(interface)类的正确方法:

struct my_interface
{
    virtual int my_function1( int param1, int param2 ) = 0;
    virtual int my_function2( const char *param ) = 0;

#if CHOOSE_DESTRUCTION_TYPE

protected:
    // Protected non-virtual destructor prevents the use of delete on the interface pointer.
    // Must be defined because it will be used as objects of derived types are destructed.
    ~my_interface() {};

#else

    // Public virtual destructor allows the use of delete on the interface pointer.
    virtual ~my_interface() = 0;

#endif

private:
    // Private copy assignment prevents "*ptr1 = *ptr2".
    // This odd syntax CAN be supported, but you probably shouldn't.
    // Only needs to be declared because nobody can call it.
    my_interface & operator=( const my_interface & );

    // Ditto for move assignment.
    my_interface & operator=( my_interface && );
};

关于C++ GetProcAddress() 找不到静态类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26365703/

相关文章:

C++11 未定义的函数引用

C++ 构造函数中的循环指针注入(inject)

c++ - 在 Visual Studio 中替换依赖项 DLL

c++ - 使用 rundll32.exe 调试 native dll,无法加载符号

c++ - 在 VB6 中使用 C++ DLL

c++ - 仅针对某些方法的模板特化

c++ - 针对 musl 编译 libstdc++

c++ - 内联类函数和共享库 (dll) 构建

Java NativeCall 库返回数据类型

c# - 如何将 C++ 数据导出到 C# 结构?