Autor Beitrag
Weedgewood
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mo 13.06.16 19:01 
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:
ausblenden Quelltext
1:
2:
3:
4:
typedef struct 
{
   WV_BED_DESCRIPTION WvBeds[WV_MAX_BEDS_PER_SERVER];
} WV_BED_LIST;

ausblenden 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;

ausblenden 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;

ausblenden 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:
ausblenden 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;

ausblenden 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;

ausblenden 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,
    }

ausblenden 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
ausblenden 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


Zuletzt bearbeitet von Weedgewood am Mo 13.06.16 20:00, insgesamt 2-mal bearbeitet
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 13.06.16 19:07 
Wie ist den WV_OPERATING_MODE definiert?
Weedgewood Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mo 13.06.16 19:34 
Hab es oben korrigiert, danke für den Hinweis...
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 13.06.16 19:57 
Möglicherweise ist der enum auf c++ Seite nicht als 32 bit Integer definiert so wie du ihn auf c# Seite zu benutzen versuchst.
Ich würde in der struct Definition auf der C# Seite WV_OPERATING_MODE mal durch einen Integer Typ ersetzen (Byte, Int16 etc) und schauen ob das dann passt.
Wenn das nicht hinhaut würde ich die Defintiton ganz durch einzelne Dummy Byte Definitionen ersetzen und solange probieren bis die Folgefelder (ConnectID etc.) stimmen.
Dann hast du zumindest die Länge des enums und man kann sich überlegen wie damit umzugehen ist.
Weedgewood Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mo 13.06.16 20:04 
Erstmal danke für Deine Hilfe. Es ist wirklich Klasse, dass Du Dir die Zeit nimmst und so schnell antwortest.

Was genau meinst Du mit Dummy-Byte-Daten? Ich habe es bereits mit byte, short, int und Long versucht.
Kann ich denn einen Dummy-Typ mit 4 Byte Länge erstellen / verwenden?

Entschuldigung, falls das eine zu simple Frage sein sollte. Eigentlich komme ich aus dem LabVIEW-Lager und nutze C# nur gelegentlich...
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mo 13.06.16 20:27 
Zitat:
Kann ich denn einen Dummy-Typ mit 4 Byte Länge erstellen / verwenden?

Nicht einen einfach mehrere ;)
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
...
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string DeviceType;
public byte Dummy1;
public byte Dummy2;
public byte Dummy3;
...
public byte DummyN;
public int ConnectID;
...

PS:
Zitat:
Entschuldigung, falls das eine zu simple Frage sein sollte. Eigentlich komme ich aus dem LabVIEW-Lager und nutze C# nur gelegentlich...

I know. Rate mal wenn ich gefunden habe beim schnellen googlen nach der Definition von WV_OPERATING_MODE ;)