LabVIEWForum.de
dll mit Pointer auf komplexe Struktur einbinden - Druckversion

+- LabVIEWForum.de (https://www.labviewforum.de)
+-- Forum: LabVIEW (/Forum-LabVIEW)
+--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein)
+---- Forum: DLL & externer Code (/Forum-DLL-externer-Code)
+---- Thema: dll mit Pointer auf komplexe Struktur einbinden (/Thread-dll-mit-Pointer-auf-komplexe-Struktur-einbinden)

Seiten: 1 2


dll mit Pointer auf komplexe Struktur einbinden - Wedgewood - 16.04.2014 22:53

Guten Abend,

seit geraumer Zeit versuche ich erfolglos, eine dll einzubinden.
Für diese dll steht mir die .h Datei zur Verfügung, trotzdem schaffe ich es nicht...
Auszug aus der header-Datei:
Code:
//     WV_BED_LIST        BedList ;
//     int                NumberOfBeds ;
//
//     int ReturnCode = WvListBeds("129.73.42.112", "guest", "winview", &BedList, &NumberOfBeds) ;
//
IMPORT_FUNCTION int WINAPI WvListBeds(const TCHAR *pServerName, const TCHAR *pUserName, const TCHAR *pPassword, WV_BED_LIST *pBedList, int *pNumberOfBeds) ;

Hier die structs:
Code:
typedef struct {
   WV_BED_DESCRIPTION WvBeds[WV_MAX_BEDS_PER_SERVER] ;
} WV_BED_LIST ;
und
Code:
typedef struct {
   TCHAR             PatientName  [WV_PATIENT_NAME_SIZE] ;
   TCHAR             PatientID    [WV_PATIENT_ID_SIZE] ;
   TCHAR             BedLabel     [WV_BED_LABEL_SIZE];
   TCHAR             CareUnit     [WV_CARE_UNIT_SIZE];
   TCHAR             FileName     [WV_FILE_NAME_SIZE];
   TCHAR             IPAddress    [WV_IP_ADDRESS_SIZE];
   TCHAR             MulticastIP  [WV_MULTICAST_IP_SIZE];
   TCHAR             DeviceType   [WV_DEVICE_TYPE_SIZE];
   WV_OPERATING_MODE DeviceStatus ;
   WV_CONNECT_ID     ConnectID ;  // 0 if not connected
} WV_BED_DESCRIPTION ;
Das Blockdiagramm und die Einstellung habe ich als Anhang beigefügt.
Wird die Funktion aufgerufen, stürzt LabVIEW komplett ab.
Muss ich per DSNewPtr.vi einen Pointer übergeben? Nur woher weiß ich dann, welche Größe der Pointer benötigt?
Die Struktur für pBedList ist auch als Anhang dabei.
Eigentlich besitze ich brauchbare C/C++ Kenntnisse und habe prinzipiell auch Erfahrung mit LabVIEW. Nur die Kombination haut leider nicht hin...

Bin für jeden Denkansatz dankbar. Momentan tendiere ich zu DSNewPtr und MoveBlock.
Da ich zum testen jedes mal einige Kilometer fahren muss, möchte ich möglichst das übliche Trial & Error Spielchen vermeiden, wenn es geht.

Gute Nacht zusammen, für heute gebe ich auf...


RE: dll mit Pointer auf komplexe Struktur einbinden - rolfk - 16.04.2014 23:25

(16.04.2014 22:53 )Wedgewood schrieb:  Muss ich per DSNewPtr.vi einen Pointer übergeben? Nur woher weiß ich dann, welche Größe der Pointer benötigt?

Nein!

Variablendeklarationen mit name[x] werden inline angelegt. D.h. diese werden mit der vollen Länge einfach in die Struktur eingebettet. In LabVIEW lässt sich das nur machen indem man einen Cluster mit der entsprechenden Anzahl Elementen einbettet.

Erschwerend kommt hier hinzu dass TCHAR je nach dem ob die DLL für Unicode compiliert wurde oder nicht ein 16 bit oder ein 8 bit character ist. Das wirst Du also noch herausfinden müssen. Wieviele Elemente Du verwenden musst musst Du im entsprechenden Header herausfinden indem Du nach den Definitionen für WV_PATIENT_NAME_SIZE und CO suchst.

Zudem ist "An Datentyp anpassen" zwar korrekt, aber nicht "Handles durch Wert" sondern "Array Data Pointer" oder wie das auf Deutsch auch übersetzt wurde.


RE: dll mit Pointer auf komplexe Struktur einbinden - Wedgewood - 17.04.2014 09:04

Hallo,
beeindruckend schnell die Antwort. Hätte ich wohl doch noch nicht sofort ausmachen sollen. Vielen Dank dafür.

Leider muss ich zu Deiner Antwort noch ein paar Fragen stellen:
Zitat:Variablendeklarationen mit name[x] werden inline angelegt. D.h. diese werden mit der vollen Länge einfach in die Struktur eingebettet
Die Übergabe des Pointers an die dll erledigt LabVIEW dann also selbstständig?
Zitat:In LabVIEW lässt sich das nur machen indem man einen Cluster mit der entsprechenden Anzahl Elementen einbettet.
Das hatte ich, glaube ich zumindest, ja eigentlich so versucht...
Zitat:TCHAR...ein 16 bit oder ein 8 bit character
Das habe ich durch
Code:
#ifdef  _UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif
gelöst (hoffe ich wenigstens)

Ich habe ja ein struct WV_BED_LIST welches das struct WV_BED_DESRIPTION enthält.
Das realisiere ich also als Cluster mit einem Cluster drin? Nicht als Array of Cluster?

Nochmals vielen Dank für jede Hilfe

Gruß
Wedgewood


RE: dll mit Pointer auf komplexe Struktur einbinden - Wedgewood - 17.04.2014 14:38

Hallo Rolf,

habe jetzt das Ausprobiert, was Du mir empfohlen hast.
Könnte das so klappen?
Oder habe ich jetzt wieder einen Denkfehler?
Kann das leider erst später ausprobieren...

Gruß

Wedgewood


RE: dll mit Pointer auf komplexe Struktur einbinden - Wedgewood - 17.04.2014 21:51

Guten Abend,
leider klappt es immer noch nicht...
Ich habe alle Kombinationen bezüglich Aufrufkonvention und aufrufendem Thread probiert. Folgende Ergebnisse:

Einstellungen: beliebigen Thread, stdcall
Access violation (0xC0000005) bei EIP=0x042FF8EA
Mögliche Ursache: E:\Thesis\Labview\Libraries\VIs\Wv List Beds.vi

Einstellungen: beliebigen Thread, C
Komplettabsturz

Einstellungen: UI Thread C
DAbort 0x0037C03D in MemoryManager.cpp

Einstellungen: UI Thread, stdcall
Ausnahme: Access violation (0xC0000005) bei EIP=0x0450F8EA
Mögliche Ursache: E:\Thesis\Labview\Libraries\VIs\Wv List Beds.vi

Was mag nur das Problem sein? Wer kann mir denn helfen?
Hilft es, wenn ich die .h Datei hoch lade?

Gruß

Wedgewood


RE: dll mit Pointer auf komplexe Struktur einbinden - BNT - 18.04.2014 08:02

Moin
Hast Du Dir schon folgenden Thread durchgelesen?
"Dereferencing Pointers ..."
https://decibel.ni.com/content/docs/DOC-9091

Gruß Holger


RE: dll mit Pointer auf komplexe Struktur einbinden - rolfk - 18.04.2014 08:19

(17.04.2014 21:51 )Wedgewood schrieb:  Guten Abend,
leider klappt es immer noch nicht...
Ich habe alle Kombinationen bezüglich Aufrufkonvention und aufrufendem Thread probiert. Folgende Ergebnisse:

Einstellungen: beliebigen Thread, stdcall
Access violation (0xC0000005) bei EIP=0x042FF8EA
Mögliche Ursache: E:\Thesis\Labview\Libraries\VIs\Wv List Beds.vi

Einstellungen: beliebigen Thread, C
Komplettabsturz

Einstellungen: UI Thread C
DAbort 0x0037C03D in MemoryManager.cpp

Einstellungen: UI Thread, stdcall
Ausnahme: Access violation (0xC0000005) bei EIP=0x0450F8EA
Mögliche Ursache: E:\Thesis\Labview\Libraries\VIs\Wv List Beds.vi

Was mag nur das Problem sein? Wer kann mir denn helfen?
Hilft es, wenn ich die .h Datei hoch lade?

Gruß

Wedgewood

Natürlich funktioniert das nicht!!!!!

Mit einem eingebetteten Cluster meinte ich einen Cluster innerhalb des Hauptclusters der n U8 oder U16 Integer Elemente enthält. U8 wenn es ASCII ist U16 wenn die DLL mit Unicode compiliert wurde.

Dabei ist n die Zahl die zwischen den eckigen Klammern ist und in Deinen Headern definiert sein muss.

Deine Deklaration

Code:
#ifdef  _UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif

ist völlig unsinnig. Das machen die Windows Headers für Dich schon.

Aber wenn Du die DLL in LabVIEW einbindest musst Du halt wissen ob sie mit UNICODE oder nicht kompiliert wurde, ansonsten geht es ziemlich verkehrt. Grundsätzlich ist es nicht sinnvoll um eine DLL mit Unicode Strings in den Aufrufparameterns zu haben da LabVIEW Strings MBCS sind und nicht Unicode, und das ist ausser für Sonderzeichen halt das gleiche wie ASCII.

Wenn Du dann so einen Cluster hast machst Du davon ein Array und konfigurierst den entsprechendne Parameter als Adapt to Type, pass Array Data Pointer.
(18.04.2014 08:02 )BNT schrieb:  Moin
Hast Du Dir schon folgenden Thread durchgelesen?
"Dereferencing Pointers ..."
https://decibel.ni.com/content/docs/DOC-9091

Gruß Holger

Holger, es geht hier nicht um Pointer in einem Cluster. Alle fixed size Elemente in einem Cluster werden durch den C Compiler inline in der Struktur angelegt.

D.h:

Code:
struct {
     int32 element1[20];
     int32 element2[10];
} MyStruct;

enhält keinerlei Pointers. Es ist ganz einfach ein Speicherblock mit 30 int32 Elementen, also 120 Byte Länge.


RE: dll mit Pointer auf komplexe Struktur einbinden - BNT - 18.04.2014 09:41

Moin Rolf
Da hat Du vollständig recht.
Ich wollte auch nur den Hinweis auf den genannten Thread verbreiten, weil das Thema mit Pointern auf komplexe Strukturen verweist.

Gruß Holger


RE: dll mit Pointer auf komplexe Struktur einbinden - Wedgewood - 18.04.2014 10:32

Guten Morgen,

vielen Dank für die Unterstützung. Den verlinkten Artikel werde ich mir gleich mal zu Gemüte führen.

@Rolf: Dein Beitrag ist toll, so langsam verstehe ich (hoffentlich) die Logik zum Verheiraten von LabVIEW mit der dll. Außerdem finde ich es super, dass Du Dir die Zeit nimmst, mir das zu erklären.

Wenn meine Familie nachher frei gibt, muss ich das unbedingt ausprobieren.

Nochmals danke an Euch beide.

Gruß

Wedgewood


RE: dll mit Pointer auf komplexe Struktur einbinden - Wedgewood - 18.04.2014 15:10

Hallo Rolf,

also ich hab gerade mal etwas "frei" bekommen...

Aus
Code:
typedef struct {
   TCHAR             PatientName  [26] ;
   TCHAR             PatientID    [20] ;
   TCHAR             BedLabel     [20];
   TCHAR             CareUnit     [20];
   TCHAR             FileName     [20];
   TCHAR             IPAddress    [20];
   TCHAR             MulticastIP  [20];
   TCHAR             DeviceType   [20];
   WV_OPERATING_MODE DeviceStatus ; //ein enum mit 11 Werten
   WV_CONNECT_ID     ConnectID ;  // 0 if not connected als int definiert
} WV_BED_DESCRIPTION ;
Erstelle ich also einen Haupt-Cluster. In diesem sind:
Cluster von 26 x U8
Cluster von 20 x U8
...
INT32 (da 32 Bit OS)
INT32

oder alternativ:
Cluster von 166 x U8
INT32
INT32

und diesen Cluster packe ich gemäß
Code:
typedef struct {
   WV_BED_DESCRIPTION WvBeds[256] ;
} WV_BED_LIST ;
256 mal in einen weiteren Haupt-Haupt-Cluster?
Kann das so klappen? Hoffentlich...

Langsam wächst in mir die Idee zu einer Wrapper-DLL. Aber noch ist der Wunsch ganz klein.
Außerdem möchte ich es jetzt eigentlich so schaffen...

Gruß

Wedgewood