C++ 使用getProcAddress在导出的DLL函数中实例化一个类

C++ 使用getProcAddress在导出的DLL函数中实例化一个类,c++,oop,visual-c++,dll,C++,Oop,Visual C++,Dll,我有以下用于DLL的.h代码,并使用getProcAddress在另一个代码中使用DLL // MathFuncsDll.h #ifdef MATHFUNCSDLL_EXPORTS #define MATHFUNCSDLL_API __declspec(dllexport) #else #define MATHFUNCSDLL_API __declspec(dllimport) #endif namespace MathFuncs { // This class is expor

我有以下用于DLL的.h代码,并使用getProcAddress在另一个代码中使用DLL

// MathFuncsDll.h

#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API __declspec(dllexport) 
#else
#define MATHFUNCSDLL_API __declspec(dllimport) 
#endif

namespace MathFuncs
{
    // This class is exported from the MathFuncsDll.dll
    class MyMathFuncs
    {
    public:
        int x = 10;
        MyMathFuncs();

           // Returns a + b + x
           MATHFUNCSDLL_API double Add(double a, double b); 

    };
}
相应的.cpp代码为

// MathFuncsDll.cpp : Defines the exported functions for the DLL application. 
//

#include "stdafx.h"
#include "MathFuncsDll.h"
#include <stdexcept>

using namespace std;

namespace MathFuncs
{
    MyMathFuncs ::MyMathFuncs()
    {
            x = 10;
    }

    double MyMathFuncs::Add(double a, double b)
    {
        return a + b + x;
    }

}
将导出函数Add,并将a和b与初始值x=10一起添加

我已经创建了一个相同的DLL文件,并使用LoadLibrary和GetProcAddress调用函数

当我不使用构造函数并直接添加10,即a+b+10时,代码运行良好。但当我执行a+b+x时,它失败了,基本上没有调用构造函数


如何使用GetProcAddress实例化这样的对象,以便在加载DLL和调用函数时得到实例化的对象方法

必须将类标记为已导出才能导出所有成员函数,包括构造函数:

class MATHFUNCSDLL_API MyMathFuncs {
...
};
之后,您可以轻松地使用该类:

MyMathFuncs funcs;
double r = funcs.Add(10.0, 10.0);

必须将类标记为导出才能导出所有成员函数,包括构造函数:

class MATHFUNCSDLL_API MyMathFuncs {
...
};
之后,您可以轻松地使用该类:

MyMathFuncs funcs;
double r = funcs.Add(10.0, 10.0);

调用构造函数不是自动的。在使用运算符NeXT但不再使用时,C++编译器通常会注意这一点。您必须使用GetProcAddress来获取构造函数地址并调用它

在此之前,您必须为对象分配内存。将其地址传递给构造函数。这就是它变得困难的地方,您不知道要分配多少内存。对于这样的简单类,它是可猜测的,但C++类编译器在类具有虚拟方法或实现多继承时应用的优化使这不实用。 <>这是一个很大的原因,与C++的互操作是如此困难,并且很难被其他语言运行时支持。唯一可靠的方法是还导出一个类工厂函数,这是一个使用新操作符创建对象并返回指针的简单函数。现在还存在销毁对象的问题,您需要某种内存管理器来确保调用运算符delete的正确实现。通常通过引用计数完成,如std::shared\u ptr


总之,你将很快重新发明COM。

调用构造函数不是自动的。在使用运算符NeXT但不再使用时,C++编译器通常会注意这一点。您必须使用GetProcAddress来获取构造函数地址并调用它

在此之前,您必须为对象分配内存。将其地址传递给构造函数。这就是它变得困难的地方,您不知道要分配多少内存。对于这样的简单类,它是可猜测的,但C++类编译器在类具有虚拟方法或实现多继承时应用的优化使这不实用。 <>这是一个很大的原因,与C++的互操作是如此困难,并且很难被其他语言运行时支持。唯一可靠的方法是还导出一个类工厂函数,这是一个使用新操作符创建对象并返回指针的简单函数。现在还存在销毁对象的问题,您需要某种内存管理器来确保调用运算符delete的正确实现。通常通过引用计数完成,如std::shared\u ptr


总之,你将很好地重新发明COM。

你需要反汇编你想要使用的DLL。然后,从中提取有关要使用的类的信息。

您需要反汇编要使用的DLL。然后,从中提取有关要使用的类的信息。

新代码是:class MathFuncsdl_API MyMathFuncs{public:int x=10;MyMathFuncs;//返回a+b+x double Adddouble a,double b;};但没有效果。仍然返回垃圾。是的,如果实例化一个类,则该值为true。但我正试图通过DLL使用它。getProcAddress只给我一个指向函数的指针,但没有给我一种实例化类和使用其对象的方法。我清楚这个问题吗?如果你能展示你的代码就好了。但无论如何,您必须了解,所有成员函数(例如,Add)还有一个参数,即指向MyMathFuncs数据结构的指针。因此,如果要调用Add,必须将其作为MyMathFuncs对象的第一个参数指针传递,该对象保存案例中的数据x=10define CONVENTION uu thiscall int\u tmaint argc,TCHAR*argv[]{string t=mathFuncsdl.dll;HINSTANCE hMod=LoadLibraryt.c_str;ifNULL==hMod{正确的方法是声明结构MyMathFuncs和导出函数double addMyMathFuncs*object,double a,double b新代码是:类MATHFUNCSDLL_API MyMathFuncs{public:int x=10;MyMathFuncs;//返回a+b+x double Adddouble a,double b;};但没有效果。
仍然返回垃圾。是的,如果实例化一个类,则该值为true。但我正试图通过DLL使用它。getProcAddress只给我一个指向函数的指针,但没有给我一种实例化类和使用其对象的方法。我清楚这个问题吗?如果你能展示你的代码就好了。但无论如何,您必须了解,所有成员函数(例如,Add)还有一个参数,即指向MyMathFuncs数据结构的指针。因此,如果要调用Add,必须将其作为MyMathFuncs对象的第一个参数指针传递,该对象保存案例中的数据x=10define CONVENTION uu thiscall int\u tmaint argc,TCHAR*argv[]{string t=mathFuncsdl.dll;HINSTANCE hMod=LoadLibraryt.c_str;ifNULL==hMod{对您来说,正确的方法是声明结构MyMaTythOffice和导出函数double AddiMyMthHyths**对象,双A,双BC++。但是我使用的是C++代码的DLL。MyMathStudio.H[ PaStBij.com /Q5P3E2WS] MyMathSoals.CPP[PaStBiN.COM/0HGBKZBE] TEST.CPP,它使用以前代码创建的DLL文件。.test.cpp无法访问MyMathFuncs.h来实例化类。它具有DLL访问权限。只有getProcAddress可以授予我添加函数的权限,但无法实例化类。有什么可能的方法可以优雅地执行此操作。好吧,这就是问题的关键所在。如果您无法访问.h文件,则无法猜测y的内存量你需要分配来创建对象。我已经解释了优雅的方法,添加一个类工厂。因此,重要的是要有一个函数来返回类的对象。此外,我不确定是否使用函数指针直接调用构造函数,因为它不能返回我任何值。因此,在这种情况下,我需要始终使用类工厂如果一个不实现类工厂,我仍然想要优雅地消费?同意。但是我使用的是C++代码的DLL。MyMathSimult.H[ PaStBij.com /Q5P3E2WS] MyMathSoals.CPP[PaStBiel.COM/0HGBKZBE] TEST.CPP,它使用了以前代码创建的DLL文件。.test.cpp无法访问MyMathFuncs.h来实例化类。它具有DLL访问权限。只有getProcAddress可以授予我添加函数的权限,但无法实例化类。有什么可能的方法可以优雅地执行此操作。好吧,这就是问题的关键所在。如果您无法访问.h文件,则无法猜测y的内存量你需要分配来创建对象。我已经解释了优雅的方法,添加一个类工厂。因此,重要的是要有一个函数来返回类的对象。此外,我不确定是否使用函数指针直接调用构造函数,因为它不能返回我任何值。因此,在这种情况下,我需要始终使用类工厂?如果一个人没有实现类工厂,而我仍然想要优雅地消费,该怎么办?