本文章将以一个机器人底盘通信程序为例,给大家展示动态链接库的一种简单暴力但灵活安全的用法:
将你的最外层类修改为适于封装成DLL的样子
一般的程序会包含多层的类封装,这里我们将最外层类拆除,也就是说这个类拆掉后,类里面的函数都成了全局函数。
如果你有一大把public变量的话,聪明的你可以将变量改为查询函数,将其内联并直接return即可:
// 一种查询底盘运行状态的函数,返回数据包的首地址并报告包长度
unsigned char* QueryState(int queryFlag, unsigned short* pkgLength); // 常见的查询函数
// 一个人物跟踪器状态报告函数(直接返回变量的查询函数)
unsigned int QueryPerson(int queryFlag); // 里面一个大switch然后各种return
如果有构造和析构函数,在public里另写一个Init和Release函数。
导出DLL(共三步)
第一步:将最外层的类拆开
// 假设我们有这样一个类
class MecanumController
{
public:
enum ChassisState
{
CHASSIS_BASE,
CHASSIS_VOLTAGE,
CHASSIS_CURRENT,
CHASSIS_ERRCODE,
// ...
};
public:
bool Open(const char* port_name);
unsigned char SendByte(unsigned char data);
unsigned char Move(unsigned short TanslationSpeed, short Yaw, short RotationAngleSpeed);
unsigned char* QueryState(int queryFlag, unsigned int bytesLength);
private:
HANDLE usart_handle;
unsigned char ReceiveByte(unsigned char data);
void Helper(void* lp);
};
可以发现,这里有一些private变量,按照常理它应该被封装起来不可见,这里我们拆开后照常写在外即可。
清静起见,你可以把private里面的声明放在源文件代码的上面。
对于enum或者typedef,如果你的函数的参数直接把枚举名字写上去了,建议改为int来减少改动。
清静起见,把enum和typedef放在源文件代码的上面。
PS:你也可以再写一个头文件,如果头文件只含枚举等方便调用的定义内容,还可与DLL一起发布,便于开发者的查看,视封装的复杂程度而定,自己进行平衡。
头文件变化如下,class段完全删除,只剩下全局声明:
// 类中的public函数
bool Open(const char* port_name);
unsigned c