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

时间:2013-05-21 07:12:39

标签: 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 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时,代码工作正常。但是当我执行+ b + x时它失败了,并且基本上没有调用构造函数。

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

3 个答案:

答案 0 :(得分:3)

调用构造函数自动。当您使用operator new时,通常由C ++编译器处理,但不再进行此操作。您必须使用GetProcAddress()来获取构造函数地址并调用它。

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

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

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

答案 1 :(得分:2)

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

class MATHFUNCSDLL_API MyMathFuncs {
...
};

之后,您可以轻松地使用此类:

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

答案 2 :(得分:0)

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