Fragensteller
P/Invoke / Marshalling - Problem mit struct

Allgemeine Diskussion
-
Moin,
momentan erstelle ich eine Wrapper-DLL für eine in C/C++ entworfene DLL.
Für diese DLL liegt mir kein Quelltext, nur die Header-Datei vor.Dank dem P/Invoke Interop Tool konnte ich bereits eine Wrapper-DLL entwerfen und kann einige Methoden aufrufen.
Leider habe ich mit einem Aufruf Probleme und hoffe nun, dass mir hier jemand weiterhelfen kann.Hier die relevanten Codeteile:
typedef struct { WV_BED_DESCRIPTION WvBeds[WV_MAX_BEDS_PER_SERVER]; } WV_BED_LIST;
typedef struct { CHAR PatientName [WV_PATIENT_NAME_SIZE]; CHAR PatientID [WV_PATIENT_ID_SIZE]; CHAR BedLabel [WV_BED_LABEL_SIZE]; CHAR CareUnit [WV_CARE_UNIT_SIZE]; CHAR FileName [WV_FILE_NAME_SIZE]; CHAR IPAddress [WV_IP_ADDRESS_SIZE]; CHAR MulticastIP [WV_MULTICAST_IP_SIZE]; CHAR DeviceType [WV_DEVICE_TYPE_SIZE]; WV_OPERATING_MODE DeviceStatus; WV_CONNECT_ID ConnectID; // 0 if not connected BOOL Wireless; CHAR HostName [WV_HOSTNAME_SIZE]; } WV_BED_DESCRIPTION;
IMPORT_FUNCTION int WINAPI WvListBeds_A(const CHAR *pServerName, const CHAR *pUserName, const CHAR *pPassword, WV_BED_LIST *pBedList, int *pNumberOfBeds, const CHAR* pDomain = 0);
Im folgenden der Code der C# Wrapper-DLL:
[StructLayout(LayoutKind.Sequential)] public struct WV_BED_LIST { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 25, ArraySubType = UnmanagedType.Struct)] public WV_BED_DESCRIPTION[] WvBeds;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public struct WV_BED_DESCRIPTION { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 26)] public string PatientName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string PatientID; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string BedLabel; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string CareUnit; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string FileName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string IPAddress; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string MulticastIP; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string DeviceType; public WV_OPERATING_MODE DeviceStatus; public int ConnectID; public bool Wireless; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)] public string HostName;
[DllImport("WvAPI.dll", BestFitMapping = false, ThrowOnUnmappableChar = true, CharSet = CharSet.Unicode, EntryPoint = "WvListBeds_A")] public static extern int WvListBeds_A([In()] [MarshalAs(UnmanagedType.LPStr)] string pServerName, [In()] [MarshalAs(UnmanagedType.LPStr)] string pUserName, [In()] [MarshalAs(UnmanagedType.LPStr)] string pPassword, ref WV_BED_LIST pBedList, ref int pNumberOfBeds);
Jetzt mein Problem:Die ersten acht Parameter werden korrekt gelesen und eingefügt. Danach scheint irgend etwas schief zu gehen:
Danach wird bei Device_Status z.B. 65601536 ausgegeben, ConnectID ist fälschlicherweise 0, Wireless fälschlicherweise true und bei HostName fehlen die ersten zwei Zeichen.Beim darauf folgenden Datensatz fehlen dann die ersten zwei Zeichen schon beim ersten Parameter. Diese zwei verschwundenen Zeichen setzten sich immer so fort und addieren sich...
Was ich bereits versucht habe, ist den Datentyp im Enum auf Byte, short, etc. zu setzten. Das Ergebnis ändert sich zwar, die beiden Zeichen fehlen trotzdem immer...
Bitte, wer hat einen Tipp für mich?
Liebe GrüßeWedgewood
- Typ geändert Dimitar DenkovMicrosoft contingent staff, Administrator Freitag, 1. Juli 2016 11:47 Warten auf Rückmeldung
Alle Antworten
-
Hallo Wedgewood,
Die ersten acht Parameter werden korrekt gelesen und eingefügt. Danach scheint irgend etwas schief zu gehen:
Danach wird bei Device_Status z.B. 65601536 ausgegeben, ConnectID ist fälschlicherweise 0, Wireless fälschlicherweise true und bei HostName fehlen die ersten zwei Zeichen.Wie ich Deiner Beschreibung entnehme, geht es um die letzten vier Felder der Struktur WV_BED_DESCRIPTION. Ich bin auf einen früheren Thread von Dir gestoßen, wo ebenfalls über das Abschneiden der ersten zwei Buchstaben und danach der ersten n*2 Zeichen berichtet wird. Ich führe hier der Vollständigkeit halber die damalige Lösung an, bei der das StructLayoutAttribute.Pack-Feld auf 1 festgelegt wird:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct WV_BED_DESCRIPTION { //... }
Gruß,
DimitarBitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „IT-Pros helfen IT-Pros“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.