动态加载调用DLL里的类

来源:互联网 发布:程序员入职心得体会 编辑:程序博客网 时间:2024/05/01 05:06

转自:http://blog.chinaunix.net/uid-283792-id-2448559.html


动态加载动态连接库能更加有效地使用内存,这在大型项目中是非常有用的一项技术。DLL中的函数可以很容易的实现动态加载调用,网上也有很多相关的介绍,但DLL中类库怎样实现动态加载调用呢?
这是我在实际项目中遇到的一个问题,可以采用类工厂方法,把对象的指针导出来的方法解决这个问题,如果需要对跨平台的支持还可以使用QT中的QLibrary代替LoadLibrary等函数。

1)与动态库调用有关的函数包括: 
(1)LoadLibrary(或MFC 的AfxLoadLibrary),装载动态库。 
(2)GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。 
(3)FreeLibrary(或MFC的AfxFreeLibrary),释放动态链接库。
2)unix上与动态库调用有关的函数包括:
(1)_打开动态链接库:dlopen,函数原型void *dlopen (const char *filename, int flag); 
dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。 
(2)取函数执行地址:dlsym,函数原型为: void *dlsym(void *handle, char *symbol); 
dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。 
(3)关闭动态链接库:dlclose,函数原型为: int dlclose (void *handle); 
dlclose用于关闭指定句柄的动态链接库,只有当此动态链接库的使用计数为0时,才会真正被系统卸载。 
(4)动态库错误函数:dlerror,函数原型为: const char *dlerror(void); 当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。 
3)QT对动态库调用的封装函数
QLibrary ( const QString & filename ) 
void * resolve ( const char * symb ) //获取要引入的函数地址

4)DLL中类库动态加载调用的实例
//动态库DLL_PUBLICCallback.dll的代码
//IPUBLICCallback.h 接口文件

typedef long HRESULT;
class IPUBLICCallback
{
public:
        virtual HRESULT Release( void )=0;
  virtual HRESULT Fun(int x)=0; 
};
extern "C" __declspec(dllexport) HRESULT CreatePUBLICCallback(IPUBLICCallback ** pp_obj);
 
 //CPUBLICCallback.h
class CIPUBLICCallback : public IIPUBLICCallback
{
public:
CIPUBLICCallback();
virtual ~CIPUBLICCallback();
HRESULT Fun(int x);
HRESULT Release(){delete this;};
};

//CPUBLICCallback.cpp
CPUBLICCallback::CPUBLICCallback()
{
}
CPUBLICCallback::~CPUBLICCallback()
{

HRESULT CPUBLICCallback::Fun(int x)
{
 ...

HRESULT CreatePUBLICCallback(IPUBLICCallback ** pp_obj)
{
*pp_obj = new CPUBLICCallback;
return TRUE;
}

//////////////
//应用程序的代码
//test.exe
//test.cpp
int main( int argc, char** argv )
{
 IPUBLICCallback* m_pPUBLICCallback;
 typedef HRESULT (*MyCreatePUBLICCallback)(IPUBLICCallback **pp_obj);
 HINSTANCE hInst = LoadLibrary("DLL_PUBLICCallback.dll");
 //QLibrary hInst( "DLL_PUBLICCallback.dll" );
 if(hInst)
 {
  MyCreatePUBLICCallback _CreatePUBLICCallback = (MyCreatePUBLICCallback) GetProcAddress(hInst, "CreatePUBLICCallback" );
  //MyCreatePUBLICCallback _CreatePUBLICCallback = (MyCreatePUBLICCallback)hInst.resolve( "CreatePUBLICCallback" );

  if ( _CreatePUBLICCallback ) 
  {
   _CreatePUBLICCallback(&m_pPUBLICCallback);
   m_pPUBLICCallback->Fun(66);
    m_pPUBLICCallback->Release();
  }
  FreeLibrary(hInst);
 }
 return 0;
}


0 0
原创粉丝点击