Reputation: 323
Ok, I'm trying to send a STRUCT from a legacy C++ application to a new C# application using Named Pipes, however I can't seem to find out how to correctly extract the information on the C# side - here is the code I currently have:
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);
Some is going horribly wrong, when I test this and trace out sSender and sCommand I get the following: Sender: LOCAL ? (? 8? ?? ?? ?? X P P ?? ???w@??w ??? ?? ???J??w x? ??? ?? ???J??w ?? #-| ,? ???? ? J??w ?? I -| ??? ???D 0 \ ?? ? ? ?? ??? ??
Command: COMMAND ?? ??? ?? ?w?? ? ?? ?0-|? ?? ,? 72-|?? ?? ??J ?? nW& "-|? @? ?-|? ?-|p?? @? ?`& ??p?? O| @? ? ?? ^+ ??????? T? f ??? l? , ??J
As you can see, in both cases the string is there (LOCAL & COMMAND) but they are both followed by tons of garbage, is there something I can do to fix this or does the cSender and cCommand have to be exactly FIXED LENGTH? I put them at 256/256 thinking "that would be more then long enough for anything I could ever need" but now I am wondering ...
Any help would be much appreciated. Thanks,
Upvotes: 0
Views: 311
Reputation: 11277
Have you tried dumping the whole of 256 byte chunks you send? Are the received bytes following LOCAL and COMMAND zero?
I suspect that you will find that you are receiving the same uninitialized tail as is present in the sender; just that C# doesn't interpret a null byte as a string terminator.
Edit -- lift adjusted struct definition into the answer from the comment
// 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;
}
Upvotes: 2