从 C++ 转换的 C# 代码不起作用
C# code converted from C++ not working
考虑以下通过RS232将数据发送到设备的C++代码。
strcpy(m_MsgBytes, "SRT1");
iTmp = finalizeNL20Message(m_MsgBytes, 4);
int CVTSSLTNL20Message::finalizeNL20Message(BYTE *pMsgData, int iInLen)
{
BYTE ucMsg[MAX_MESSAGE_LENGTH];
ucMsg[0] = MSG_STX; // 0x02
ucMsg[1] = NL20_BLOCK_ID; // ox01
ucMsg[2] = ATTR_CMD; // 'C'
memcpy(&ucMsg[3], pMsgData, iInLen);
ucMsg[3 + iInLen] = MSG_ETX;
ucMsg[4 + iInLen] = calculateNL20Checksum(ucMsg, 4 + iInLen);
ucMsg[5 + iInLen] = MSG_CR;
ucMsg[6 + iInLen] = MSG_LF;
memcpy(pMsgData, ucMsg, 7 + iInLen);
return 7 + iInLen;
}
BYTE CVTSSLTNL20Message::calculateNL20Checksum(const BYTE *pData, int iInLen)
{
BYTE ucChk = 0;
for (int iCnt = 0; iCnt < iInLen; iCnt++)
ucChk = ucChk ^ pData[iCnt];
return ucChk;
}
我用 C# 重写了这段代码,如下所示:
public static string Generate()
{
return RIONNLHelper.FinalizeMessage("SRT1");
}
public static string FinalizeMessage(string data)
{
//STX=0x02 NL20BLOCKID=0x01 Command=C (Command from computer)
data = "x02x01C" + data;
//ETX=0x03
data += "x03";
data += (char)calculateNL20CheckSum(data);
data += "rn";
return data;
}
public static byte calculateNL20CheckSum(string data)
{
byte chk = 0;
foreach (byte b in Encoding.ASCII.GetBytes(data))
{
chk ^= b;
}
return chk;
}
并且字符串在发送前转换为字节数组
字节 = 数据。选择(c=>(byte(c(.ToArray((; 现在的问题是,C# 代码永远不会从设备获得对这些请求的响应。它确实会发送回其他数据,因此波特率和所有正确的数据。
我对缓冲区从C++代码转换有些疑问。 0x020x01C 数据 0x03校验和 \r
成为
\x02\x01C 数据 \x03 校验和 \r
否则,重写校验和计算是否正确?首先计算字节的校验和,然后转换回字符
这是一个奇怪的问题。与往常一样,我创建了一个单元测试。然后我使用 CLR 构建了C++版本C++并进行测试以将输出与您的输入"SRT1"进行比较。最初,它失败了
C++ version: 02 01 43 53 52 54 31 03 27 0d 0a
C# version: 02 1c 53 52 54 31 03 79 0d 0a
那个1C看起来相当熟悉...
错误似乎在于假设字符串"x02x01C" + data
;与"x02" + "x01" + "C" + data;
相同,而十六进制转义将继续解释数字,直到找到不是十六进制数字的字符。因此,"C"成为十六进制转义的一部分。
分解文字允许解析器将"C"解析为单独的字符,然后单元测试通过。
嗯...您的问题可能是某些代码使用Encoding.ASCII.GetBytes(finalString)
最终将string
转换为byte[]
,但校验和可能是>= 0x7F,因此是非 ASCII 字符。在Generate
后手动将string
转换为byte[]
,如下所示:
string result = Generate();
byte[] bytes = new byte[result.Length];
for (int i = 0; i < result.Length; i++)
{
bytes[i] = (byte)result[i];
}
只是为了确保更改:
foreach (byte b in Encoding.ASCII.GetBytes(data))
{
chk ^= b;
自
foreach (char ch in data)
{
chk ^= (byte)ch;
或者,您可以使用将值0x00-0xFF
映射到 unicode 值0x0000-0x00FF
的Encoding.GetEncoding("iso-8859-1")
。
如Pete Kirkham
所述,除非您对字符>0x7F
有一些data
,否则校验和将被<0x7F。这是因为^
运算符将仅返回 (1 ^ 0( 或 (0 ^ 1( 的 1,因此您必须在某个地方将 8 位位于 1 处,才能使 8 位为 1 的校验和。
- 为什么这段代码不起作用,我该如何解决?
- 为什么这些完全相似的代码不起作用?
- 我不明白为什么我的代码不起作用并且需要更长的时间来运行
- 我正在尝试解决一个需要数组总和值但代码不起作用的问题,我想做这样的事情
- 注释一行使代码工作,而没有它,代码不起作用
- 我的C++合并排序代码不起作用。我在这里错过了什么?
- C ++函数重新定义(代码不起作用 - 逻辑错误)
- 试图找到一个数字的平方根,但代码不起作用。C++
- 字符串代码不起作用
- 我正在努力在随机数组中查找最小值,有人知道为什么我的代码不起作用?C++
- 从 C++ 转换的 C# 代码不起作用
- 有人可以解释我,为什么我的代码不起作用吗?
- 当我使用长整型时,我的代码不起作用,它与 int 一起工作得很好
- 无法在控制面板中创建轨道栏.示例代码不起作用
- CUDA我的共享内存代码不起作用,我缺少什么
- 为什么 C++ 中的 shell 脚本代码不起作用?
- 为什么C++代码不起作用(strncpy_s)?
- 模板函数声明为 void - 代码不起作用?
- 无法弄清楚为什么这个Arduino代码不起作用?
- "check if member exists using enable_if"中修改的代码不起作用