利用抽象接口从DLL里导出C++类

来源:互联网 发布:java商城开源 编辑:程序博客网 时间:2024/05/24 02:00

参考文献: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;
}

 

0 0
原创粉丝点击