J'essaye de marshal une structure d'un byte []. Chaque partie fonctionne sauf marshaling une chaîne. Il me ressemble comme un BSTR:Marshal.PtrToStructure chaîne marshaled est vide
06 00 00 00 48 00 65 00 6c 00 6c 00 6f 00 21 00 00 00
Donc, c'est une longueur de 4 octets puis "Bonjour!" en unicode avec un double terminateur null. Voici le code de marshaling avec lequel j'ai joué:
string auto = Marshal.PtrToStringAuto(nextSchedulePtr); // returns "Hello!"
string ansi = Marshal.PtrToStringAnsi(nextSchedulePtr); // returns "H"
string uni = Marshal.PtrToStringUni(nextSchedulePtr); // returns "Hello!"
string bstr = Marshal.PtrToStringBSTR(nextSchedulePtr); // returns "Hel"
Schedule schedule = (Schedule)Marshal.PtrToStructure(nextSchedulePtr, typeof(Schedule)); // returns "" with UnmanagedType.BStr and UnmanagedType.LPWStr
La méthode 1 appelle de toute façon la méthode 3, donc c'est logique. Cependant, je ne peux spécifier aucun type dans l'attribut [MarshalAs (UnmanagedType.X)] qui permettra à la structure de renvoyer quoi que ce soit de significatif.
J'épuré la structure à ceci:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Schedule
{
[MarshalAs(UnmanagedType.BStr)]
public string Name;
}
J'ai littéralement essayé toutes les valeurs valides pour UnmanagedType.X et soit ils jette AccessViolationExceptions ou retourner une chaîne vide ou le retour indésirable. Aucun renvoie "Bonjour!". Suis-je incapable de charger ces données dans une structure?
Remarque: Je ne peux pas modifier les données, elles sont gravées dans la pierre. Je peux, cependant, changer mon code. J'ai également épinglé l'octet [] afin qu'il ne soit pas GC'ed.
Cela prend tout son sens maintenant que j'y pense. Je vous remercie. C'est énervant, mais au moins il y a une solution de contournement que je peux abstraire du code client. – Gary
Yeh, interop avec le code non managé peut sucer. Au moins, vous avez affaire à P/Invoke et non à JNI ... – cdhowie
Comment cela peut-il fonctionner avec une chaîne de taille fixe? – Tsury