ACE_Export与自定义导出符号(结贴)
来源:互联网 发布:冬不拉调音软件下载 编辑:程序博客网 时间:2024/04/28 16:03
不得不佩服ACE的跨平台强大之处
如果你需要在Windows下创建dll项目供其他项目使用。
你创建dll项目的代码要导出才能被外部访问,这个是由于Windows的动态链接库默认访问级别为私有导致的,所以只有导出的接口才会被外部访问。
当你打算导出的时候只需要使用ACE自带的导出宏即可:
使用ACE导出符号头文件
头文件应该像这个样子:
#ifndef CONFIGLOADER_H#define CONFIGLOADER_H#include "ace/Log_Msg.h"class ACE_Export ConfigLoader{public:ConfigLoader(void);~ConfigLoader(void); void load_from_file(void); void load_from_db(void);};#endif
源文件正常,无需任何变动:
/************************************************************************//* 配置加载类 *//************************************************************************/#include "ConfigLoader.h"ConfigLoader::ConfigLoader(void){}ConfigLoader::~ConfigLoader(void){}void ConfigLoader::load_from_db(void){ ACE_DEBUG((LM_DEBUG,"ConfigLoader::load_from_db(void) run"));}void ConfigLoader::load_from_file(void){ ACE_DEBUG((LM_DEBUG,"ConfigLoader::load_from_file(void) run"));}
但是我发现当有继承关系的时候,尤其是基类是抽象基类但也要导出的时候,比如有virtual函数的时候这种方式就不行了,要用下面的这种方式(单独指定导出某个具体的函数,而不是整个类):
#ifndef COMMUNICATER_H#define COMMUNICATER_H#include "ace/ACE_export.h"class Communicater{public: ACE_Export Communicater(void); ACE_Export virtual void run_collect() = 0; ACE_Export virtual ~Communicater(void);};#endif
ACE的等价代码
#ifndef COMMUNICATER_H#define COMMUNICATER_H//#include "ace/ACE_export.h"#ifdef COMMUNICATER_EXPORTS#define COMMUNICATER_API __declspec(dllexport) #else#define COMMUNICATER_API __declspec(dllimport) #endifclass Communicater{public: COMMUNICATER_API Communicater(void); COMMUNICATER_API virtual void run_collect() = 0; COMMUNICATER_API virtual ~Communicater(void);};#endif
反正就是要对每个接口单个导出,而不是导出类,不知道为何
即可编译生成dll,供其他项目使用,多棒!
具体操作参考:http://blog.csdn.net/calmreason/article/details/6989390中官方网站教程(主要是VC++工程的“项目引用”功能 )
自己实现导出符号
由于ACE的导出符号多少针对ACE特定的要求,而且针对不同平台其导出宏我们不好确定是哪一个,所以,为了简单起见,自己也模仿定义了自己的导出符号:
头文件
SCP_Export.h头文件
#ifndef SCP_EXPORT_H#define SCP_EXPORT_H #ifdef WIN32 //for windows #ifdef SCP_EXPORTS //for windows generate dll,you have to define SCP_EXPORTS in your preprocessor #define SCP_Export __declspec(dllexport) #else #define SCP_Export //for windows as source file #endif #else //for Linux #ifdef SCP_EXPORTS //for Linux as source file #define SCP_Export #else #define SCP_Export //for Linux generate dll #endif #endif#endif
使用自定义导出符号:
无论你是想以源文件方式使用自己的类,还是打算将自己的类放到dll里面,你都只需要做两件事(1)(2)
(1)可以在自己的类的头文件中包含SCP_Export.h头文件
(2)在有可能会被导出的地方加上SCP_Export声明
(3)只有一种情况:windows下,你打算把自己的类放到dll中,这时候你需要在preprocessor里加上SCP_EXPORTS预编译符号,表示你的类在dll里面是可以被外部的程序调用的。
在普通类使用导出符号示例:
CollectorInfor.h
/************************************************************************//* 采集器实体类 *//************************************************************************/#ifndef COLLECTORINFOR_H#define COLLECTORINFOR_H#include <string>using namespace std;#include "ace/INET_Addr.h"#ifndef SCP_EXPORT_H#include "SCP_Export.h"#endifclass SCP_Export CollectorInfor{public:CollectorInfor(void);~CollectorInfor(void); u_short get_port_number (void) const; const char *get_host_name (void) const; const string to_string(void) const;private: ACE_INET_Addr local_addr;};#endif
包含虚函数的基类使用导出符号的示例:
#ifndef COMMUNICATER_H#define COMMUNICATER_H#include <vector>using namespace std;#include "ace/INET_Addr.h"#include "ace/Task.h"#ifndef COMMUNICATERINFOR_H#include "CommunicaterInfor.h"#endif#ifndef SCP_TYPE_H#include "scp_type.h"#endif#ifndef SCP_EXPORT_H#include "SCP_Export.h"#endif#ifndef MESSAGEQUEUE_H#include "MessageQueue.h"#endifclass Communicater{public: //派生类必须实现的方法 SCP_Export virtual void run_collect(void) = 0; SCP_Export const CommunicaterInfor& get_infor(void); //派生类必须实现的方法 SCP_Export Communicater(const CommunicaterInfor&); SCP_Export virtual ~Communicater(void);protected: vector<id_type> has_collector_id_; const CommunicaterInfor& infor_;};//派生类必须实现的方法extern "C" SCP_Export Communicater* CreateCommunicater(CommunicaterInfor&);#endif
派生类使用导出函数:
Communicater_103.h
#ifndef COMMUNICATER_103_H#define COMMUNICATER_103_H#include <string>using namespace std;#include "ace/Log_Msg.h"#include "ace/Event_Handler.h"#include "ace/Date_Time.h"#include "ace/WIN32_Proactor.h"#include "ace/INET_Addr.h"#include "ace/SOCK_Dgram.h"#include "ace/Message_Block.h"#include "ace/OS.h"#include "ace/Proactor.h"#include "ace/Task.h"#include "ace/Asynch_Acceptor.h" #include "SCP_Export.h"#ifndef COMMUNICATER_H#include "Communicater.h"#endif#ifndef SCP_TYPE_H#include "scp_type.h"#endif#ifndef CONFIGLOADER_H#include "ConfigLoader.h"#endif#ifndef GLOBAL_H#include "global.h"#endif/*8 链路传输过程 8.1 客户机/服务器模型 系统采用标准TCP/IP 的客户机-服务器模型进行通信。应用服务数据单元(ASDU)报 文使用高可靠性的TCP 数据流传输,主站(监控/远动)作为服务器端在约定的1048(418H) 号TCP 端口上被动侦听等待,子站(保护/测控装置)作为客户端主动发起连接。TCP 传输 的数据保证可靠性但无报文边界,因而需要在接收方进行适当的解粘包处理。 为了适应多主站情况,系统通过辅助UDP 链路实现主站IP 的动态识别。在此辅助UDP 链路中,子站作为服务器端在约定的1032(408H)号UDP 端口被动等待接收,主站作为客 户端主动发送UDP 广播报文。子站接收UDP 报文后获得主站IP 地址信息可用来发起TCP 连接,同时可取得时间信息进行时钟同步。*//** * @class UDPSender * * @brief The class will be created by <main>. */class UDPSender : public ACE_Handler { public: UDPSender (void); ~UDPSender (void); //FUZZ: disable check_for_lack_ACE_OS ///FUZZ: enable check_for_lack_ACE_OS int open (const ACE_TCHAR *host, u_short port); protected: // These methods are called by the freamwork /// This is called when asynchronous writes from the dgram socket /// complete virtual void handle_write_dgram (const ACE_Asynch_Write_Dgram::Result &result); private: /// Network I/O handle ACE_SOCK_Dgram sock_dgram_; /// wd (write dgram): for writing to the socket ACE_Asynch_Write_Dgram wd_; }; class Communicater_103 : public Communicater ,public ACE_Service_Handler{public: Communicater_103(const CommunicaterInfor&); ~Communicater_103(void); void run_collect(void);private: UDPSender udp_sender; ACE_Asynch_Read_Stream reader_; };extern "C" SCP_Export Communicater* CreateCommunicater(CommunicaterInfor&);#endif
名称空间中的函数和类的导出:
#ifndef GLOBAL_H#define GLOBAL_H#include <iostream>#include <string>#include <sstream>#include <vector>using namespace std;#ifndef SCP_EXPORT_H#include "SCP_Export.h"#endif namespace global{ int SCP_Export string_to_id(const string& dll_name); string SCP_Export to_hex_string(const string& temp_string); string SCP_Export long_long_to_string(long long id); template<typename Result,typename Para> Result SCP_Export lexical_cast(Para para) { stringstream ss; ss<<para; Result result; ss>>result; return result; } template<typename T> void SCP_Export print(T begin,T end) { while(begin != end) { cout<<*begin++<<" "; } cout<<endl; };}#endif
在编译环境中添加导出符号宏:
有了以上代码文件的准备,只需要在你用到这些代码的项目中添加导出宏即可使用:右键项目名》属性》Configuration Properties》C/C++》Preprocessor》Preprocessor Definitions》添加宏SCP_EXPORTS
这样你的项目就可以生成一个dll供其他项目使用,在其他项目中只需要包含你定义的头文件,并引用此项目即可,具体见:http://blog.csdn.net/calmreason/article/details/6989390
- ACE_Export与自定义导出符号(结贴)
- 16 驱动模块的符号表与符号导出
- 绘制自定义符号三(读取自定义符号)
- linux内核模块(2)导出符号
- 导出内核符号错误!(err -22)
- TrueTypeFont文件中符号数据导出与绘制
- linux模块导出符号EXPORT_SYMBOL与EXPORT_SYMBOL_GPL的区别
- java导出excel,自定义列与行
- 导出lib所有符号
- 【原创】内核符号导出
- 模块导出符号
- 模块导出符号
- 内核符号导出
- linux内核导出符号
- 内核符号导出
- linux内核导出符号
- linux内核导出符号
- 内核符号导出
- 进程与线程的一个简单解释
- VBSocket编程(Winsock控件创建TCP/IP客户机/服务器程序)
- lines container
- Fiddler中script小试牛刀
- linux内核cdev_init系列函数(字符设备的注册)
- ACE_Export与自定义导出符号(结贴)
- java基础之IO流中的BufferedReader和BufferedWriter
- 2015 百度笔试的一道经典题目
- [数位dp] hdu 3886 Final Kichiku “Lanlanshu”
- file_operations结构体详细分析
- 小白的LINQ TO SQL学习
- gyb-e改造说明
- POJ 1716 区间最小点个数
- Android ListView 滚动翻页效果