寻找一种更好的方法来表示无符号字符数组
Looking for a better way to represent unsigned char arrays
我有一堆这样的声明:
unsigned char configurePresetDelivery[] = { 0x7E, 0x01, 0x00, 0x20, 0x38, 0x0B, 0x04, 0x03, 0xF2, 0x40, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3 };
unsigned char beginPresetDelivery[] = { 0x7E, 0x01, 0x00, 0x20, 0x3C, 0x01, 0x04, 0x2B };
unsigned char configureDirectDelivery[] = { 0x7E, 0x01, 0x00, 0x20, 0x37, 0x02, 0X03, 0XF2, 0xD5 };
...
这些是我通过串行端口发送到一台设备的命令。
有没有更好的方式来表示这些?在结构或 class 之类的东西中?
我仅限于 C++98。
谢谢。
如何表示命令在很大程度上取决于您的程序要发送的命令序列。
如果您的程序完全是通用的并且需要能够按字面意思发送任何可能的字节序列,那么 const unsigned char
数组(或者 const uint8_t
如果您想要一点点更明确)可能是要走的路。
另一方面,如果您的协议中有一些您知道永远不会更改或需要有任何例外的 "rules",那么您可以将代码写入 include/enforce规则而不是盲目地发送程序员提供的原始序列(并希望程序员正确输入它们)。
例如,如果您知道串行设备总是要求每个命令都以前缀 0x7E, 0x01, 0x00, 0x20
开头,那么您就可以减少重复(从而减少打字错误的机会) ) 通过从您的序列中删除该前缀并让您的发送函数自动添加它,例如:
const unsigned char configurePresetDelivery[] = { 0x38, 0x0B, 0x04, 0x03, 0xF2, 0x40, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3 };
const unsigned char beginPresetDelivery[] = { 0x3C, 0x01, 0x04, 0x2B };
const unsigned char configureDirectDelivery[] = { 0x37, 0x02, 0X03, 0XF2, 0xD5 };
const unsigned char prefix[] = {0x7e, 0x01, 0x00, 0x20};
void send_prefix_and_command(const unsigned char * cmdWithoutPrefix, int numBytes)
{
send(prefix, sizeof(prefix));
send(cmdWithoutPrefix, numBytes);
}
[...]
send_prefix_and_command(configurePresetDelivery, sizeof(configurePresetDelivery));
... 并且(更进一步)如果您知道您的某些命令序列将根据 运行 时间参数而变化,那么与其手动编码每个变化,您可以创建一个命令生成器函数来为您执行此操作(从而将可能容易出错的生成步骤封装到单个代码位置,因此 maintain/debug 只有一个例程而不是很多例程)。例如
// This is easier to do using std::vector, so I will use it
std::vector<unsigned char> generatePresetDataCommand(unsigned char presetID, unsigned short presetValue)
{
// I'm totally making this up just to show an example
std::vector<unsigned char> ret;
ret.push_back(0x66);
ret.push_back(0x67);
ret.push_back(presetID);
ret.push_back((presetValue>>8)&0xFF); // store high-bits of 16-bit value into a byte
ret.push_back((presetValue>>0)&0xFF); // store low-bits of 16-bit value into a byte
return ret;
}
// Convenience wrapper-function so later code can send a vector with less typing
void send_prefix_and_command(const std::vector<unsigned char> & vec)
{
send_prefix_and_command(&vec[0], vec.size());
}
[...]
// The payoff -- easy one-liner sending of a command with little chance of getting it wrong
send_prefix_and_command(generatePresetDataCommand(42, 32599));
我有一堆这样的声明:
unsigned char configurePresetDelivery[] = { 0x7E, 0x01, 0x00, 0x20, 0x38, 0x0B, 0x04, 0x03, 0xF2, 0x40, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3 };
unsigned char beginPresetDelivery[] = { 0x7E, 0x01, 0x00, 0x20, 0x3C, 0x01, 0x04, 0x2B };
unsigned char configureDirectDelivery[] = { 0x7E, 0x01, 0x00, 0x20, 0x37, 0x02, 0X03, 0XF2, 0xD5 };
...
这些是我通过串行端口发送到一台设备的命令。
有没有更好的方式来表示这些?在结构或 class 之类的东西中?
我仅限于 C++98。
谢谢。
如何表示命令在很大程度上取决于您的程序要发送的命令序列。
如果您的程序完全是通用的并且需要能够按字面意思发送任何可能的字节序列,那么 const unsigned char
数组(或者 const uint8_t
如果您想要一点点更明确)可能是要走的路。
另一方面,如果您的协议中有一些您知道永远不会更改或需要有任何例外的 "rules",那么您可以将代码写入 include/enforce规则而不是盲目地发送程序员提供的原始序列(并希望程序员正确输入它们)。
例如,如果您知道串行设备总是要求每个命令都以前缀 0x7E, 0x01, 0x00, 0x20
开头,那么您就可以减少重复(从而减少打字错误的机会) ) 通过从您的序列中删除该前缀并让您的发送函数自动添加它,例如:
const unsigned char configurePresetDelivery[] = { 0x38, 0x0B, 0x04, 0x03, 0xF2, 0x40, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3 };
const unsigned char beginPresetDelivery[] = { 0x3C, 0x01, 0x04, 0x2B };
const unsigned char configureDirectDelivery[] = { 0x37, 0x02, 0X03, 0XF2, 0xD5 };
const unsigned char prefix[] = {0x7e, 0x01, 0x00, 0x20};
void send_prefix_and_command(const unsigned char * cmdWithoutPrefix, int numBytes)
{
send(prefix, sizeof(prefix));
send(cmdWithoutPrefix, numBytes);
}
[...]
send_prefix_and_command(configurePresetDelivery, sizeof(configurePresetDelivery));
... 并且(更进一步)如果您知道您的某些命令序列将根据 运行 时间参数而变化,那么与其手动编码每个变化,您可以创建一个命令生成器函数来为您执行此操作(从而将可能容易出错的生成步骤封装到单个代码位置,因此 maintain/debug 只有一个例程而不是很多例程)。例如
// This is easier to do using std::vector, so I will use it
std::vector<unsigned char> generatePresetDataCommand(unsigned char presetID, unsigned short presetValue)
{
// I'm totally making this up just to show an example
std::vector<unsigned char> ret;
ret.push_back(0x66);
ret.push_back(0x67);
ret.push_back(presetID);
ret.push_back((presetValue>>8)&0xFF); // store high-bits of 16-bit value into a byte
ret.push_back((presetValue>>0)&0xFF); // store low-bits of 16-bit value into a byte
return ret;
}
// Convenience wrapper-function so later code can send a vector with less typing
void send_prefix_and_command(const std::vector<unsigned char> & vec)
{
send_prefix_and_command(&vec[0], vec.size());
}
[...]
// The payoff -- easy one-liner sending of a command with little chance of getting it wrong
send_prefix_and_command(generatePresetDataCommand(42, 32599));