参考文献:http://eli.thegreenplace.net/2011/09/16/exporting-c-classes-from-a-dll/
这种方法的好处就是通过接口类可以非常方便的显示的导出一个类,并调用其函数。
下面以vc2008为例介绍实现过程
第一步:用VC2008创建一个空的WIN32项目,项目的类型选择DLL
第二步:新建头文件generic_interface.h,在里面声明一个接口类IKlass
class IKlass {
public:
virtual void destroy() = 0;
virtual int do_stuff(int param) = 0;
virtual void do_something_else(double f) = 0;
};
第三步:新建c++文件MyKlass.cpp,在里面实现接口类,也就是要导出的类MYKlass
#include "generic_interface.h"
#include <iostream>
#include <windows.h>
using namespace std;
class MyKlass : public IKlass {
public:
MyKlass()
: m_data(0)
{
cerr << "MyKlass constructor\n";
}
~MyKlass()
{
cerr << "MyKlass destructor\n";
}
void destroy()
{
delete this;
}
int do_stuff(int param)
{
m_data += param;
return m_data;
}
void do_something_else(double f)
{
int intpart = static_cast<int>(f);
m_data += intpart;
}
private:
int m_data;
};
extern "C" __declspec(dllexport) IKlass* __cdecl create_klass()
{
return new MyKlass;
}
这里有两个值得注意到地方,一个是MyKlass实现了接口IKlass,一个是最后的工厂函数能实现MyKlass的实体。
到这一步,DLL的创建就完成了,直接编译就可以生成DLL了。
第四步:显示调用DLL
这一步先创建一个控制台的应用程序,把generic_interface.h的路径添加到项目的附加路径上
用下面的代码即可显示调用DLL
#include "generic_interface.h"
#include <iostream>
#include <windows.h>
using namespace std;
// A factory of IKlass-implementing objects looks thus
typedef IKlass* (__cdecl *iklass_factory)();
int main()
{
// Load the DLL
HINSTANCE dll_handle = ::LoadLibrary(TEXT("testintfacedll.dll"));
if (!dll_handle) {
cerr << "Unable to load DLL!\n";
return 1;
}
// Get the function from the DLL
iklass_factory factory_func = reinterpret_cast<iklass_factory>(
::GetProcAddress(dll_handle, "create_klass"));
if (!factory_func) {
cerr << "Unable to load create_klass from DLL!\n";
::FreeLibrary(dll_handle);
return 1;
}
// Ask the factory for a new object implementing the IKlass
// interface
IKlass* instance = factory_func();
// Play with the object
int t = instance->do_stuff(5);
cout << "t = " << t << endl;
instance->do_something_else(100.3);
int t2 = instance->do_stuff(0);
cout << "t2 = " << t2 << endl;
// Destroy it explicitly
instance->destroy();
::FreeLibrary(dll_handle);
return 0;
}