无法通过NamedPipe [C#]在PtrToStructure之后提取数据

时间:2009-09-09 21:26:35

标签: c#

好的,我正在尝试使用命名管道将遗留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处,认为“对于我可能需要的任何东西来说,这将足够长”,但现在我想知道......

非常感谢任何帮助。 谢谢,

1 个答案:

答案 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;
}