下载地址:http://pan.baidu.com/s/1pJuKTM7
ACE对dll的管理介绍
ACE加载的dll其生命周期分为两种情况:(1)被ACE_DLL管理(2)被ACE_DLLManager(这是个单例)管理。
如果是情况(1),默认情况下ACE_DLL对象析构的时候就把其管理的dll实例释放掉,这样我们之前在dll中创建的对象就不复存在(这个假设在刘鑫的观点之上);这种情况下dll里面创建对象的范围就比较小,只能在ACE_DLL的生命周期内进行。通过在open函数中指明参数:close_handle_on_destruction 的值为true来做到,如果你不设为true,那么dll的生命期就不再受ACE_DLL控制,这通常交给下面的(2)
int open (const ACE_TCHAR *dll_name,
int open_mode = ACE_DEFAULT_SHLIB_MODE,
bool close_handle_on_destruction = true);
如果是情况(2)则由全局的单例ACE_DLL_Manager来统一管理,比如finit调用的时候由ACE_DLL_Manager负责将其释放。这个生命周期就取决于ACE_DLL_Manager何时主动释放加载的dll,这种情况也有一个前提,那就是,如果dll仍然是通过ACE_DLL加载进来的,那么就要用ACE_DLL(false)来构造一个ACE_DLL对象,并调用此对象的open方法时也指明不对其生命期进行管理ACE_DLL dll;dll.open("MyDLL",0,0);
仅仅使用ACE_DLL管理dll的示例
本例最简单的调用dll中的类对象的print方法打印Hello World。
网上的例子不太好用,当时觉得既然ACE_DLL是个类库,那就是头文件包含不就行了。看了ACE下载包里面的ACE_Main项目之后仿照他的自己写了。
创建 dll 类型的项目 Dll_Project,设置项目的output目录为..lib(目的是将其他项目也设置为这个目录到时候dll和exe在同一个文件夹下)
//子定义的类用于生成dll
A.h
#ifndef A_H
#define A_H
#include <iostream>
class Base
{
public:
virtual void print(void) const = 0;
};
class A : public Base
{
public:
A(void);
~A(void);
void print(void) const ;
};
extern "C" __declspec(dllexport) Base* create_A(void);
#endif
A.cpp
#include "A.h"
A::A(void)
{
}
A::~A(void)
{
}
void A::print(void) const
{
std::cout<<"class A::print()";
}
Base* create_A(void)
{
return new A();
}
创建 dll 项目 Use_ACE_DLL,设置项目的output目录为..lib(目的是将其他项目也设置为这个目录到时候dll和exe在同一个文件夹下)
(1)将这个类放到dll类型的项目中生成dll,在 相邻的project中准备引用这个dll,
(2)在项目中加载ACE库
(3)在项目中引用头文件A.h
在同一个solution中新创建一个用来引用dll的ACE项目,
main函数如下
#include "A.h"
#include "ace/Log_Msg.h"
#include "ace/DLL.h"
typedef Base* (*PTR_FUN) (void);
int main(int, char *[])
{
ACE_DEBUG((LM_DEBUG, ACE_TEXT("Hello, ACE !\n")));
ACE_DLL dll;
int retval = dll.open(ACE_DLL_PREFIX ACE_TEXT("Dll_Project"));//dll file name
if (retval != 0)
{
ACE_ERROR_RETURN ((LM_ERROR,
"%p",
"dll.open"),
-1);
}
void *void_ptr = dll.symbol (ACE_TEXT ("create_A")); // export name
PTR_FUN ac = reinterpret_cast<PTR_FUN> (void_ptr);
if (ac == 0)
{
ACE_ERROR_RETURN ((LM_ERROR,
"%p",
"dll.symbol"),
-1);
}
{
Base* pa=ac ();
pa->print();
}
dll.close ();
return 0;
};
设置:将项目的输入out目录设置为..\lib(方便多个项目生成的结果能够互相在运行时调用)
这里没有讲环境搭建等信息,在其他文章中有
运行结果如下:
其实,对于ACE调用外部服务最专业的还是ACE_Service_Config,专门动态处理dll服务。在运行时处理
请见:http://blog.csdn.net/calmreason/article/details/20690319
Linux版本参考:http://blog.163.com/ecy_fu/blog/static/44451262009571180157/