我有关于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和调用函数时,我得到实例化的对象方法。
答案 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。然后,从中提取有关要使用的类的信息。