INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.


Antwort schreiben 

Problem bei Aufruf einer dll



Wenn dein Problem oder deine Frage geklärt worden ist, markiere den Beitrag als "Lösung",
indem du auf den "Lösung" Button rechts unter dem entsprechenden Beitrag klickst. Vielen Dank!

07.09.2022, 05:52
Beitrag #1

swoc Offline
LVF-Neueinsteiger


Beiträge: 3
Registriert seit: Sep 2022

2020
2008
DE



Problem bei Aufruf einer dll
Hallo zusammen,

ich habe ein interessantes Phänomen beim Aufruf einer dll - und zwar geht es hier um einen ganz einfachen Aufruf folgender Funktion:

/**
* Get the error message, in case an error happend
*/
LBUS_API const char* __stdcall getErrorMessage(int errorVal);

also ich übergebe der Funktion einen numerischen Wert und bekomme einen String, der den Fehler beschreibt...nichts anderes wie die Umwandlung Fehlercode in Text.

Der definierte Bereich geht von -19 bis 11. Bei manchen Werten bekomme ich jedoch nur ein paar Sonderzeichen 0x03 0x00 0x00 zurück. (siehe z.b. -17, -16)

-19 File too old or Wrong File
-18 devicSTM:STARTe not found
-17 
-16 
-15 File not readable
...

Jetzt stellt sich für mich die Frage, warum es in den meisten Fällen funktioniert und manchmal nicht.

hier ein Screenshot meiner Konfiguration:
       

hier der Code in LV:
   

Vielleicht noch ein zusätzlicher nützlicher Hinweis:
Wenn ich in meiner Knotenkonfiguration errorVal von I32 auf I16 umstelle, dann funktionieren die ganzen negativen Werte nicht mehr, also alles unter 0 liefert dann diese Sonderzeichenkette und von 0 bis 11 verhält es sich wie vorher: mehrheitlich ok, manchmal Sonderzeichen
   

Ich benutze LV2020 32bit, die dll sollte laut meinem Kollegen auch 32bit sein
Betriebssystem ist Windows 10 Pro, 64bit

Vielen Dank im Voraus für euer Feedback.
Christian
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
Anzeige
07.09.2022, 09:30
Beitrag #2

jg Offline
CLA & CLED
LVF-Team

Beiträge: 15.864
Registriert seit: Jun 2005

20xx / 8.x
1999
EN

Franken...
Deutschland
RE: Problem bei Aufruf einer dll
Hallo Christian,

das die Umstellung von I32 auf I16 dann bei negativen "I16" Zahlen Blödsinn liefert, ist logisch. Stell einfach mal die Anzeige eine I16 oder I32, bei dem du Dezimal -1 eingibst, in LabVIEW auf Binary um, dann wirst du feststellen, dass bei I16 ganz viele gesetzte Bits fehlen.

Zur "seltsamen" Rückgabe: Was sagt denn die Doku der DLL dazu? Was soll denn z.B. bei -16 zurückkommen?

Gruß, Jens

Wer die erhabene Weisheit der Mathematik tadelt, nährt sich von Verwirrung. (Leonardo da Vinci)

!! BITTE !! stellt mir keine Fragen über PM, dafür ist das Forum da - andere haben vielleicht auch Interesse an der Antwort!

Einführende Links zu LabVIEW, s. GerdWs Signatur.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
08.09.2022, 06:45
Beitrag #3

swoc Offline
LVF-Neueinsteiger


Beiträge: 3
Registriert seit: Sep 2022

2020
2008
DE



RE: Problem bei Aufruf einer dll
Hallo Jens,

vielen Dank für dein Feedback.

Die Thematik (Probleme im negativen Bereich) mit dem falschen Datentyp (I16 statt I32) hab ich mir eh schon gedacht und ist auch nachvollziehbar.

Die dll ist von uns selber und funktioniert auch in anderen Programmen problemlos, nur eben in LabVIEW leider nicht.

Ich glaube, das liegt einfach an der schlechten Kompatibilität der Datentypen und Speicherverwaltung etc. (zumindest habe ich das so wahrgenommen, wo ich mir die Beiträge im Forum bezüglich Verwendung einer dll durchgelesen habe).

Ich habe mal versucht, den Code in LabVIEW nachzubauen, daraus eine dll zu erstellen und dann zu schauen, wie der Funktionsprototyp aussieht.

Das ganze hat dann folgendes ergeben:
void __cdecl GetErrorMessage(int32_t errorVal, LStrHandle *String);

Bei der ursprünglichen dll sieht das so aus:
LBUS_API const char* __stdcall getErrorMessage(int errorVal);

Ich weiß nicht ob es andere Möglichkeiten gibt, die ursprüngliche dll fehlerfrei zu nutzen, aber ich hab mir gedacht, vielleicht kann man eine Art "Zwischenschnittstelle" oder "Übersetzer-Schnittstelle" einbauen zwischen der ursprünglichen dll, und dem, was man gut in LabVIEW einbinden kann. In dieser Thematik kenn ich mich aber leider gar nicht aus.

Für Tipps bin ich sehr dankbar.

Gruß
Christian
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
08.09.2022, 08:03
Beitrag #4

Martin.Henz Offline
LVF-Team
LVF-Team

Beiträge: 417
Registriert seit: Jan 2005

2.5.1 bis 20
1992
kA

74363
Deutschland
RE: Problem bei Aufruf einer dll
Hallo Christian,

bei einer Funktion die als Return Type char * hat ohne dass der Aufrufer einen Puffer und die Puffergröße übergeben muss, gehen bei mir ehrlich gesagt erst mal die Alarmglocken an. Wo kommt denn der String her? Wer muss den Speicher wieder frei geben oder ist es ein pointer auf einen statischen String?

Wenn ich das nicht beantworten kann, dann lasse ich da meine finger weg und wenn ich selbst eine DLL schreibe, dann mache ich so etwas erst gar nicht.
(Den Fall meide ich seit ewigen Zeiten wie die Pest und kann deine Frage(n) daher auch nur bedingt beantworten)

Der Aufrufer stellt den Puffer zur Verfügung und sagt, wie groß der Puffer ist. Übergibt der Aufrufer eine Puffergröße von 0 und/oder einen Null Pointer, dann liefert die Funktion entweder einen Fehler oder sie sagt, wie groß der Puffer sein sollte. Wenn es denn unbedingt sein soll, dass der DLL Funktion den Speicher allokiert, dann bitte nur Optional und nur wenn beschrieben wird, wo der Puffer her kommt. Ein Beispiel für letzteren Fall wäre z.B. FormatMessage

LabVIEW hat seinen eigenen Speichermanager und du hast so gut wie gar keinen Einfluss darauf, wann Speicher allokiert wird und wann er von LabVIEW wieder freigegeben wird. Wenn eine Funktion also ein char * zurück liefert und du diesen als LStrHandle in Labview haben möchtest, dann muss LabVIEW in der Call Library Node den C-String auf den char * zeigt umkopieren, also zunächst einmal dessen Länge feststellen, Speicher in der passenden größe allokieren und den String umkopieren.

Das sollte IMHO auch erst einmal gut funktionieren. Ein CStr endet beim ersten 0x00 Zeichen. Ist die Zeichenkette z.B. in UTF-16 kodiert, dann kann das nicht mehr funktionieren. Es funktioniert auch dann nicht, wenn die aufrufende Funktion den benötigten Speicher dynamisch allokiert und der Aufrufer den Speicher wieder freigeben soll.

Zunächst wären also ein paar Fragen zu klären:
Wo kommt der Speicher her auf den der Pointer zeigt? Und gegebenenfalls auch: Wer und wie wird dieser Speicher wieder freigegeben?
Wie ist der String kodiert?

Weil ihr die DLL ja selbst erstellt, würde ich jetzt einfach den Entwickler der DLL freundlich aber bestimmt darauf hinweisen, dass diese Funktion keine so gute Idee ist und ihn bitten (oder auch mit einer Tasse Kaffee "bestechen") einfach zusätzlich noch folgende Funktion zu implementieren:

const int __stdcall getErrorMessageExt(int errorVal, char *Buffer, int BufferSize);

Die Funktion prüft, ob der übergebene Puffer groß genug ist für den String (und Buffer ungleich NULL ist). Falls das passt, dann wird die Fehlermeldung dort hineinkopiert.
Return Wert: Anzahl der Zeichen im String. Im Fehlerfall ist der Return Wert null.

Das sollte in ein paar Minuten inclusive Doku erledigt sein und spart auf der anderen Seite viele Stunden an Nachfragen und Überlegungen (ganz unabhängig von der Programmiersprache stellt sich das immer). Alleine die Zeit für dieses Postings dauert schon länger als das Implementieren einer solchen Funktion. Es wäre überflüssig wenn es eine solche Funktion bereits geben würde.

Martin Henz
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
08.09.2022, 12:58
Beitrag #5

swoc Offline
LVF-Neueinsteiger


Beiträge: 3
Registriert seit: Sep 2022

2020
2008
DE



RE: Problem bei Aufruf einer dll
Hi Martin,

vielen Dank für deinen Input.

Ich habe es jetzt so versucht:
in der dll (h-Datei):
/*!
* GetErrorMessage
*/
void __cdecl GetErrorMessage(int32_t errorVal, char String[], int32_t LNge);

in LabVIEW:
           

Schaut soweit gut aus, ich denke jetzt habe ich das Prinzip dahinter verstanden - werde es demnächst auch mit Strukturen/Clustern versuchen.

Danke und Gruß
Christian
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
08.09.2022, 17:01
Beitrag #6

Martin.Henz Offline
LVF-Team
LVF-Team

Beiträge: 417
Registriert seit: Jan 2005

2.5.1 bis 20
1992
kA

74363
Deutschland
RE: Problem bei Aufruf einer dll
Hi Christian,

viel Spass mit den Clustern und Strukturen.

Martin Henz
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
Anzeige
Antwort schreiben 


Möglicherweise verwandte Themen...
Themen Verfasser Antworten Views Letzter Beitrag
  Speicherüberlauf bei häufigen Aufruf einer dll maexx 2 3.800 07.03.2010 15:52
Letzter Beitrag: maexx
  bei Aufruf einer Funktion in shell32.dll schmiert LV manchmal ab toaran_ 3 4.524 21.01.2010 20:28
Letzter Beitrag: rolfk
  Problem Aufruf einer C-DLL mit Array Pointer hcl86 4 6.300 01.05.2009 10:18
Letzter Beitrag: hcl86
  Problem beim Einbinden einer DLL preacha 18 16.813 25.09.2008 11:51
Letzter Beitrag: baliik

Gehe zu: