好的,我正在尝试使用命名管道将遗留C ++应用程序中的STRUCT发送到新的C#应用程序,但是我似乎无法找到如何在C#端正确提取信息 - 这是我目前拥有的代码:
C++ Sending Code
// Structure for message
struct MESSAGE
{
CHAR cSender[256];
CHAR cCommand[256];
};
// Sending the MESSAGE
DWORD dwWrote = 0
MESSAGE msg;
strcpy(msg.cSender, "LOCAL");
strcpy(msg.cCommand, "COMMAND");
WriteFile(pipe, msg, sizeof(msg), dwWrote);
C# Recieving Code:
// Corresponding C# MESSAGE structure
[StructLayout(LayoutKind.Sequential)]
public struct MESSAGE
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] cSender;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] cCommand;
}
MESSAGE msg = new MESSAGE();
byte[] byteData = new byte[Marshal.SizeOf(msg)];
uint uBytesRead;
bool fSuccess = ReadFile(hPipeInst,
byteData,
(uint)byteData.Length,
out uBytesRead,
IntPtr.Zero); // no overlapping
// Generate Structure at the C# side
IntPtr ptr = Marshal.AllocHGlobal(byteData.Length);
try
{
Marshal.Copy(byteData, 0, ptr, byteData.Length);
msg = (MESSAGE)Marshal.PtrToStructure(ptr, typeof(MESSAGE));
}
finally
{
Marshal.FreeHGlobal(ptr);
}
// Extract Sender & Command to be used
string sSender = Encoding.ASCII.GetString(msg.cSender);
string sCommand = Encoding.ASCII.GetString(msg.cCommand);
有些是非常错误的,当我测试这个并追踪sSender和sCommand我得到以下内容: 发件人:LOCAL? (?8??? ?? ?? XPP ?? ??? w @ ?? w ??? ?? ??? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? |,??????J ?? w ?? I - | ??? ??? D 0 \ ?? ?? ?? ?? ?? ?? ?? ??
命令:COMMAND ?? ??? ?? ?W ^? ? ?? ?0〜|? ?? ,? 72- | ?? ?? ?? ?? ??纳瓦&安培; “ - |?@? - |?? - | p ?? @ ????????????????????????????????????????????????????????? ?,?? J
正如你所看到的,在这两种情况下,字符串都在那里(LOCAL& COMMAND),但它们后面跟着大量的垃圾,我可以做些什么来解决这个问题,或者cSender和cCommand是否必须完全正确固定长度?我把它们放在256/256处,认为“对于我可能需要的任何东西来说,这将足够长”,但现在我想知道......
非常感谢任何帮助。 谢谢,
答案 0 :(得分:2)
你试过转储你发送的整个256字节块吗? LOCAL和COMMAND之后的接收字节是否为零?
我怀疑您会发现您收到与发件人相同的未初始化的尾巴;只是C#没有将空字节解释为字符串终止符。
编辑 - 将调整后的结构定义提升为评论的答案
// Corresponding C# MESSAGE structure
[ StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct MESSAGE
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string cSender;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string cCommand;
}