Weedgewood - Mo 13.06.16 19:01
Titel: DLLImport in C#, Problem mit enum in struct
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:
Quelltext
1: 2: 3: 4:
| typedef struct { WV_BED_DESCRIPTION WvBeds[WV_MAX_BEDS_PER_SERVER]; } WV_BED_LIST; |
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| 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; |
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| typedef enum WV_OPERATING_MODE { WV_OPERATING_MODE_INVALID = 0, WV_OPERATING_MODE_MONITORING, WV_OPERATING_MODE_STANDBY, WV_OPERATING_MODE_READY, WV_OPERATING_MODE_BUSY, WV_OPERATING_MODE_PAPEROUT, WV_OPERATING_MODE_DOOR_OPEN, WV_OPERATING_MODE_COMM_FAILURE, WV_OPERATING_MODE_DEVICE_FAILURE, WV_OPERATING_MODE_NA, WV_OPERATING_MODE_DISCHARGE = WV_OPERATING_MODE_NA, WV_OPERATING_MODE_LAST = WV_OPERATING_MODE_NA } WV_OPERATING_MODE; |
Quelltext
1:
| 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:
C#-Quelltext
1: 2: 3: 4: 5:
| [StructLayout(LayoutKind.Sequential)] public struct WV_BED_LIST { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 25, ArraySubType = UnmanagedType.Struct)] public WV_BED_DESCRIPTION[] WvBeds; |
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| [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; |
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| public enum WV_OPERATING_MODE { WV_OPERATING_MODE_INVALID = 0, WV_OPERATING_MODE_MONITORING, WV_OPERATING_MODE_STANDBY, WV_OPERATING_MODE_READY, WV_OPERATING_MODE_BUSY, WV_OPERATING_MODE_PAPEROUT, WV_OPERATING_MODE_DOOR_OPEN, WV_OPERATING_MODE_COMM_FAILURE, WV_OPERATING_MODE_DEVICE_FAILURE, WV_OPERATING_MODE_NA, WV_OPERATING_MODE_DISCHARGE = WV_OPERATING_MODE.WV_OPERATING_MODE_NA, WV_OPERATING_MODE_LAST = WV_OPERATING_MODE.WV_OPERATING_MODE_NA, } |
C#-Quelltext
1: 2:
| [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...
Ach ja, es existiert ein nicht genutzter Eintrag
Quelltext
1:
| #define WV_DEVICE_STATUS_SIZE 4 |
in der Header-Datei.
Könnte WV_OPERATING_MODE vielleicht nur 4 Byte groß sein? Würde dann eventuell die verschwundenen Zeichen erklären...
Bitte, wer hat einen Tipp für mich?
Liebe Grüße
Wedgewood