2009-09-09 7 views
0

Ok, j'essaie d'envoyer un STRUCT à partir d'une application C++ héritée vers une nouvelle application C# en utilisant Named Pipes, mais je n'arrive pas à trouver comment correctement extraire les informations du côté C# - est ici le code que j'ai actuellement:Impossible d'extraire des données après PtrToStructure via NamedPipe [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); 

Certains va terriblement mal, quand je l'essai et tracer sSender et sCommand je reçois les éléments suivants: Auteur: LOCAL? (? 8? ?? XPP ??? ??? w @ ?? w ?? ?? ??? J ?? wx? ??? ?? ??? J ?? w ?? # - |,? ????? J ?? w ?? I - | ??? ??? D 0 \ ???? ?? ??? ??

Commande: COMMANDE ?? ???? ?? w???? 0- |? ??,? 72- | ?? ?? ?? J ?? nW & "- |? @?? - |?? - | p ?? @?? `& ?? p ?? O | @?? ??^+ ??????? T? F ??? l?, ?? J

Comme vous pouvez le voir, dans les deux cas, la chaîne est là (COMMANDE) mais ils sont tous les deux suivis par des tonnes d'ordures, y a-t-il quelque chose que je peux faire pour réparer cela ou est-ce que cSender et cCommand doivent être exactement FIXED LENGTH? Je les ai mis à 256/256 plus puis assez longtemps pour tout ce dont je pourrais avoir besoin "mais maintenant je me demande ...

Toute aide serait grandement appréciée. Merci,

Répondre

2

Avez-vous essayé de vider l'ensemble des blocs de 256 octets que vous avez envoyés? Les octets reçus après LOCAL et COMMAND sont-ils à zéro?

Je suspecte que vous trouverez que vous recevez la même queue non initialisée que présente dans l'expéditeur; juste que C# n'interprète pas un octet nul comme un terminateur de chaîne.

Edition - ascenseur définition ajustée struct dans la réponse du commentaire

// 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; 
} 
+0

Ok - qui fait sens (et ressemble, vous avez raison) ... des suggestions sur la façon de résoudre ce problème? Existe-t-il un moyen d'analyser les chaînes en C# afin de jeter les déchets? – Shaitan00

+1

Étendez l'attribut StructLayout à [StructLayout (LayoutKind.Sequential, CharSet = CharSet.Ansi)] et définissez les membres à être des chaînes, classées comme UnmanagedType.ByValTStr (conserver le même SizeConst). –

+0

J'ai fait le changement, mais maintenant ReadFile échoue avec l'erreur suivante: "Plus de données est disponible" ... des indices? – Shaitan00

Questions connexes