C++;GetProcAddress()可以';找不到静态类的方法 我需要动态加载C++中的DLL。< /P>

C++;GetProcAddress()可以';找不到静态类的方法 我需要动态加载C++中的DLL。< /P>,c++,dll,dllexport,dynamic-loading,getprocaddress,C++,Dll,Dllexport,Dynamic Loading,Getprocaddress,我按照本教程创建了dll,一切正常 然后,我遵循了这一点,并对console应用程序进行了如下调整: 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;

我按照本教程创建了dll,一切正常

然后,我遵循了这一点,并对console应用程序进行了如下调整:

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;
}
typedef-DOUBLE(回调*DllFunc)(DOUBLE,DOUBLE);
int _tmain(int argc,_TCHAR*argv[]
{
HINSTANCE hDLL;//DLL的句柄
DllFunc dllFunc1;
双p1=1.0,p2=2.0,r;
hDLL=加载库(L“MathFuncsDL”);
如果(hDLL!=NULL)
{

cout使用dumpbin或Dependency Viewer等工具检查导出的函数名。这将允许您诊断哪些可能的故障模式适用于您的案例:

  • 函数未导出,或
  • 函数已导出,但名称已修饰,或
  • 函数以您期望的名称导出,但您键入的名称不正确

  • <>欢迎使用C++的名字。编译器添加到你的函数名的所有漏洞是为了确保每个具有唯一签名的函数都有唯一的名字。微软的名字是单向的,GCC/CLAN是另一个。它不是标准化的,但是特定OS上的编译器都用相同的方式命名,这样它们都可以得到。一路走

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

    在我工作过的库中,有一个导出的C函数用于初始化库并获取接口指针。在本例中,“接口”表示一个抽象的虚拟基类,没有数据,只有虚拟函数

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

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

    请转储dll的符号,然后添加它。很难猜出这个名称是从哪里来的,看起来你只是猜到了。它应该是“?Multiply@MyMathFuncs@MathFuncs@@SANNN@Z"对于MSVC++编译器。在DLL上使用Dumpbin.exe/exports来查看名称。通过链接DLL项目生成的.lib文件,您可以避免执行类似的可怕操作。您使用显示导出名称的屏幕截图更新了问题。当然,我们已经完成了。您还期待什么?实际上没有更多。。。出于好奇,我问编译器为什么要添加这些符号..Khouri Giordano的回答,下面,解释一下!)