h文件定义struct,cpp文件实现struct。

近日,做了一个项目,暂且称其为:RC,遇到了些问题,也想办法解决了它们,现在分享出来,希望有助于朋友们的学习交流与工作,不过还是要谢谢我的老总,是他给了我压力,好了,不多说,先把遇到的问题一一列出:


1、因为我是研发一个DLL,提供重要接口与硬件交互,所以必然少不了数据封装的好助手:struct,同时,它也支持C中不能支持的构造,重载,还有继承。所以,我需要提供:RC.h、RC.dll、RC.lib这三个文件,但是,我不可能把struct内部详细构造、重载、乃至继承都在RC.h中实现,这是我老总要求的,估计也是目前通行的,但是我又要实现这些个具体的操作,这可如何是好?


2、在研发一个DLL中很可能需要对这个库的初始化和清理,这不可能交给客户来完成,这又怎么办?


3、如何做到全局常量的比较规范?


... ...


我现在把主要的代码贴出,也相信大家的能力,能够从中知道如何解决问题,如何更好的优化,我就不多说了;


DLL的初始化和清理函数暂且定位:RC_Init() 和 RC_Clear();


另外新建一个h文件,暂且定位:RC_CommDef.h,我用它存放全局常量以及 RC_Init() 和 RC_Clear()的定义;


RC.h:


/// 定义WinSock信息
struct tagWinSockInfo {
/// IP地址,一般格式为×××.×××.×××.×××,例如:192.168.0.100
string strIpAddr; 
/// 端口,一般是在区间[1, 65536]内;
UINT iPort; 
}; 
/// 定义串口信息
struct tagCommInfo {
UINT uiPort; /// 串口号,一般在区间[1, 256]内;
/*
波特率,一般是这几种:... 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200, 128000, 256000;
在Windows系统中WinBase.h文件中有定义:
#define CBR_110             110
#define CBR_300             300
#define CBR_600             600
#define CBR_1200            1200
#define CBR_2400            2400
#define CBR_4800            4800
#define CBR_9600            9600
#define CBR_14400           14400
#define CBR_19200           19200
#define CBR_38400           38400
#define CBR_56000           56000
#define CBR_57600           57600
#define CBR_115200          115200
#define CBR_128000          128000
#define CBR_256000          256000
*/
DWORD dwBaud; 
/// 数据位,一般是这几种:... 5, 6, 7, 8;
BYTE ucDataBits; 
/*
停止位,一般是这几种:1, 1.5, 2;
在Windows系统中WinBase.h文件中有定义:
#define ONESTOPBIT          0
#define ONE5STOPBITS        1
#define TWOSTOPBITS         2
*/
BYTE ucStopBit; 
/* 
校验位,一般是这几种:None, Odd, Even, Mark, Sapce;
在Windows系统中WinBase.h文件中有定义:
#define NOPARITY            0
#define ODDPARITY           1
#define EVENPARITY          2
#define MARKPARITY          3
#define SPACEPARITY         4
*/
BYTE ucParity; 
};


... ...


RC_CommDef.h:

#include "RC.h"

#define MAX_COM_PORT 256 /// 最大串口号
#define MAX_IP_PORT 65535 /// 最大IP端口号

... ... 

typedef struct _XC_RC_WINSOCK_INF : public tagWinSockInfo {
_XC_RC_WINSOCK_INF(void) { 
strIpAddr.assign("");
iPort = 0;

/// 考虑如果有扩展的情况,即:在基结构体的基础上再添加数据变量。
_XC_RC_WINSOCK_INF& operator = (const _XC_RC_WINSOCK_INF& t) {
if (this != (&t)) {
strIpAddr.assign(t.strIpAddr);
iPort = t.iPort;
}
/// 
return (*this);
}
/// 
_XC_RC_WINSOCK_INF& operator = (const tagWinSockInfo& t) {
if (this != (&t)) {
strIpAddr.assign(t.strIpAddr);
iPort = t.iPort;
}
/// 
return (*this);
}
/// 
bool operator < (const _XC_RC_WINSOCK_INF& other) const
{
const int _iVal = strIpAddr.compare(other.strIpAddr);
/// 
if (0 > _iVal) 
return true;
else if (0 == _iVal) 
return iPort < other.iPort;
/// 
return false;
}
/// 
bool operator == (const _XC_RC_WINSOCK_INF& other) const
{
return 0 == strIpAddr.compare(other.strIpAddr) && iPort == other.iPort;
}
} XC_RC_WINSOCK_INF_st, *XC_RC_WINSOCK_INF_pst;


typedef struct _XC_RC_COMM_INF : public tagCommInfo {
_XC_RC_COMM_INF(void) {
uiPort = 0;
dwBaud = 0;
ucDataBits = 8;
ucStopBit = ONESTOPBIT; //0,1,2=0,1.5,2; 
ucParity = NOPARITY; /// 0-4=no,odd,even,mark,space; 
}
///  
_XC_RC_COMM_INF& operator = (const _XC_RC_COMM_INF& t) {
if (this != (&t)) {
uiPort = t.uiPort;
dwBaud = t.dwBaud;
ucDataBits = t.ucDataBits;
ucStopBit = t.ucStopBit;
ucParity = t.ucParity;
}
/// 
return (*this);
}
/// 
_XC_RC_COMM_INF& operator = (const tagCommInfo& t) {
if (this != (&t)) {
uiPort = t.uiPort;
dwBaud = t.dwBaud;
ucDataBits = t.ucDataBits;
ucStopBit = t.ucStopBit;
ucParity = t.ucParity;
}
/// 
return (*this);
}
/// 
bool operator < (const _XC_RC_COMM_INF& other) const 

return uiPort < other.uiPort;
}
/// 
bool operator == (const _XC_RC_COMM_INF& other) const 

return uiPort == other.uiPort && dwBaud == other.dwBaud && ucDataBits == other.ucDataBits && ucStopBit == other.ucStopBit && ucParity == other.ucParity;
}
} XC_RC_COMM_INF_st, *XC_RC_COMM_INF_pst;


/*
* 函数功能:
*     初始化

* 参数描述:

* 返回值:

*/
void RC_Init(void);


/*
* 函数功能:
*     释放所有占用内存。

* 参数描述:

* 返回值:

*/
void RC_Clear(void);


RC.cpp:
#include "RC_CommDef.h"

RC_Init()

{}

RC_Clear() 

{}


dllmain.cpp:


#include "RC_CommDef.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH: /// 进程被调用
{
// 记住,千万不再在DllMain函数中建立线程,像如下的WaitForSingleObject
// 将使得程序发生死锁,详细可参考 Window高级编程指南.pdf 的P-433的DLL系列化问题
//hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc,NULL,0,&dwThreadId);
//WaitForSingleObject(hThread,INFINITE);
/// Disables the DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications for the specified 
/// dynamic-link library (DLL). This can reduce the size of the working set for some applications.
/// Parameters: hModule [in] - A handle to the DLL module for which the DLL_THREAD_ATTACH and 
///                            DLL_THREAD_DETACH notifications are to be disabled.
/// Return value: If the function succeeds, the return value is nonzero.
DisableThreadLibraryCalls(hModule);


RC_Init();


break;
}
case DLL_THREAD_ATTACH: /// 线程被调用
case DLL_THREAD_DETACH: /// 线程被停止
break;
case DLL_PROCESS_DETACH: /// 进程被停止
RC_Clear();
break;
}
/// 
return TRUE;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值