2

我有 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 并调用函数时获得实例化对象方法。

4

3 回答 3

3

调用构造函数不是自动的。这通常在您使用时由 C++ 编译器处理,operator new但现在不再这样做。您将不得不使用 GetProcAddress() 来获取构造函数地址并调用它。

在你这样做之前,你必须为对象分配内存。您将其地址传递给构造函数。这就是困难的地方,您不知道要分配多少内存。对于像这样的简单类是可以猜测的,但是当类具有虚拟方法或快速实现多重继承时,C++ 编译器应用的优化使这不切实际。

这是与 C++ 互操作如此困难且其他语言运行时支持不佳的一个重要原因。唯一可靠的方法是导出一个类工厂函数,这是一个使用 new 运算符创建对象并返回指针的简单函数。现在销毁对象也存在问题,您需要某种内存管理器来确保operator delete也调用了正确的实现。通常通过引用计数来完成,例如 std::shared_ptr<>。

总而言之,您将顺利地重新发明 COM。

于 2013-05-21T08:05:51.193 回答
1

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

class MATHFUNCSDLL_API MyMathFuncs {
...
};

之后,您可以按原样轻松使用此类:

MyMathFuncs funcs;
double r = funcs.Add(10.0, 10.0);
于 2013-05-21T07:19:39.040 回答
0

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

于 2013-05-21T12:23:54.100 回答