LabVIEWForum.de
DLL einbinden mit "void * func" - 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 einbinden mit "void * func" (/Thread-DLL-einbinden-mit-void-func)



DLL einbinden mit "void * func" - kaiman - 14.10.2011 13:42

Moin liebe Forumuser,

ich versuche mich gerade zum ersten mal daran eine dll einzubinden - mehr oder weniger erfolgreich.Undecided
Das Problem ist, dass ich mir nicht ganz sicher bin, wie ich die Funktion korrekt aufrufe. Sie sieht wie folgt aus:
int_stdcall func(int Handle, void * Img, int Flg, int * LCount, int * Header)
Die DLL ist von einer Kamera und mit der Funktion rufe ich nach einigem Vorgeplänkel das Bild ab - so zumindest der Plan. Die Initialisierung funktioniert auch soweit ganz gut, zumindest erhalte ich keine Fehlermeldungen! Bei dem Funktionsaufruf zum Abholen des Bildes bekomme ich aber immer einen Fehlercode von der DLL zurück.
Ich bin mir nicht sicher, wie ich das "void * Img" übergeben muss... Ich dachte eigentlich, dass ich ein 16bit-Array mit der Größe "Anzahl der Pixel + Header" übergeben muss, bzw. den Array Data Pointer. Ich hab schon sämtliche Einstellungen durchprobiert, bin aber zu keinem besseren Ergebnis gekommen.

Die Parameter übergebe ich wie folgt:
Handle: Numeric, signed16, Value -> (Funktioniert bei den anderen Funktionen auch)
Img: Array, unsigned16, Array Data Pointer (so meine bisherige Annahme)
Flg: Numeric, signed16, Value
LCount: Numeric, unsigned16, Pointer to Value
Header: Numeric, signed16, Pointer to Value

Hat jemand von euch eine Idee einen Tipp, was ich falsch machen könnte? Hab im Bezug auf das Einbinden von DLLs noch keine Erfahrung.

Danke schon mal im Voraus für eure Hilfe.
Schöne Grüße und schon mal ein schönes und sonniges Wochende,
KaiCool


RE: DLL einbinden mit "void * func" - rolfk - 14.10.2011 13:56

(14.10.2011 13:42 )kaiman schrieb:  Moin liebe Forumuser,

ich versuche mich gerade zum ersten mal daran eine dll einzubinden - mehr oder weniger erfolgreich.Undecided
Das Problem ist, dass ich mir nicht ganz sicher bin, wie ich die Funktion korrekt aufrufe. Sie sieht wie folgt aus:
int_stdcall func(int Handle, void * Img, int Flg, int * LCount, int * Header)
Die DLL ist von einer Kamera und mit der Funktion rufe ich nach einigem Vorgeplänkel das Bild ab - so zumindest der Plan. Die Initialisierung funktioniert auch soweit ganz gut, zumindest erhalte ich keine Fehlermeldungen! Bei dem Funktionsaufruf zum Abholen des Bildes bekomme ich aber immer einen Fehlercode von der DLL zurück.
Ich bin mir nicht sicher, wie ich das "void * Img" übergeben muss... Ich dachte eigentlich, dass ich ein 16bit-Array mit der Größe "Anzahl der Pixel + Header" übergeben muss, bzw. den Array Data Pointer. Ich hab schon sämtliche Einstellungen durchprobiert, bin aber zu keinem besseren Ergebnis gekommen.

Die Parameter übergebe ich wie folgt:
Handle: Numeric, signed16, Value -> (Funktioniert bei den anderen Funktionen auch)
Img: Array, unsigned16, Array Data Pointer (so meine bisherige Annahme)
Flg: Numeric, signed16, Value
LCount: Numeric, unsigned16, Pointer to Value
Header: Numeric, signed16, Pointer to Value

Hat jemand von euch eine Idee einen Tipp, was ich falsch machen könnte? Hab im Bezug auf das Einbinden von DLLs noch keine Erfahrung.

Danke schon mal im Voraus für eure Hilfe.
Schöne Grüße und schon mal ein schönes und sonniges Wochende,
KaiCool
Mit dieser Information lässt sich grundsätlich nicht viel spezifisches sagen. Ohne genaue Beschreibung dieser Funktion ist da wenig zu machen. Dinge die es zu beachten gilt:

- stdcall calling convention
- Du musst dieses Array in LabVIEW mittels Initialize Array auch auf die richtige Grösse initialisieren, das kann die DLL Funktion nicht tun, und LabVIEW kann das auch nicht für Dich tun, da es keine Ahnung darüber haben kann was die Funktion benötigt.
- int ist ein 32 bit integer.


RE: DLL einbinden mit "void * func" - kaiman - 14.10.2011 14:31

Hi rolfk,

Danke für deine fixe Antwort.
- stdcall hab ich immer gemacht, weil LV komplett abgeschmiert wenn ich c einstelle
- int ist int32... warum auch nicht einfach mal int32 wie in LV einführen, das wär viel zu einfach. Lieber mit short, long, int und dem ganzen Kram rumschlagen...
- Initialisierung hatte ich auch schonmal probiert, bringt aber leider auch nichts. Der Fehler bleibt der selbe.

Was würdest du denn vermuten, wie ich das Array übergeben muss? Meine Vermutung ist, dass der Fehler darin liegt.

(14.10.2011 13:56 )rolfk schrieb:  Mit dieser Information lässt sich grundsätlich nicht viel spezifisches sagen. Ohne genaue Beschreibung dieser Funktion ist da wenig zu machen. Dinge die es zu beachten gilt:

- stdcall calling convention
- Du musst dieses Array in LabVIEW mittels Initialize Array auch auf die richtige Grösse initialisieren, das kann die DLL Funktion nicht tun, und LabVIEW kann das auch nicht für Dich tun, da es keine Ahnung darüber haben kann was die Funktion benötigt.
- int ist ein 32 bit integer.



RE: DLL einbinden mit "void * func" - rolfk - 14.10.2011 14:57

(14.10.2011 14:31 )kaiman schrieb:  Hi rolfk,

Danke für deine fixe Antwort.
- stdcall hab ich immer gemacht, weil LV komplett abgeschmiert wenn ich c einstelle
- int ist int32... warum auch nicht einfach mal int32 wie in LV einführen, das wär viel zu einfach. Lieber mit short, long, int und dem ganzen Kram rumschlagen...
- Initialisierung hatte ich auch schonmal probiert, bringt aber leider auch nichts. Der Fehler bleibt der selbe.

Was würdest du denn vermuten, wie ich das Array übergeben muss? Meine Vermutung ist, dass der Fehler darin liegt.

Die Mondphase?

Mal im Ernst, das Einizge was sich hier vermuten lässt hier ist dass Du etwas mit der Initialisierung des Arrays nicht gut machst. Ohne Initialisierung gehts ohnehin nicht. Das ist kein opionaler Schritt sondern absolut unverzichtbar willst Du überhaupt eine Chance haben um nicht einen Schutzverletzungsfehler zu bekommen.

Und dann muss man rausfinden was die DLL den hier haben möchte. Ist es ein Array von x * y Pixels? Muss dieses Array auch noch Raum für ein Border verfügbar haben? Ist ein Pixel ein 8 bit, 16 bbit oder 32 bit Wert oder etwas anderes?

Sollte dieses Array effektiv ein Array of Array sein? In diesem Fall hast Du leider Pech und geht es eigentlich nicht mehr ohne eine extra Wrapper DLL.

Also ransetzen und Informationen zusammensuchen. Das musst Du wirklich selber tun.


RE: DLL einbinden mit "void * func" - kaiman - 14.10.2011 15:23

Ok, die Mondphase kann ich ausschließen - obwohl...wir haben gerade Vollmond...
In der Beschreibung steht nur, dass ich für Img ausreichend Speicher allozieren muss mit einer Größe von (1728 + 153600)bytes für ein 320*240 Bild. Jedes Pixel hat 16bit, weshalb also jedes Pixel 2 byte braucht. Da aber ja mit "void * Img" nur der Zeiger auf den allozierten Speicher übergeben wird (soweit mein Verständnis) ist da nichts genaueres definiert. In der Beschreibung steht: "Img: memory for the image (header and image data)prepared by the called application".
Aber wie kann ich nur den Speicher übergeben?


RE: DLL einbinden mit "void * func" - rolfk - 14.10.2011 17:00

(14.10.2011 15:23 )kaiman schrieb:  Ok, die Mondphase kann ich ausschließen - obwohl...wir haben gerade Vollmond...
In der Beschreibung steht nur, dass ich für Img ausreichend Speicher allozieren muss mit einer Größe von (1728 + 153600)bytes für ein 320*240 Bild. Jedes Pixel hat 16bit, weshalb also jedes Pixel 2 byte braucht. Da aber ja mit "void * Img" nur der Zeiger auf den allozierten Speicher übergeben wird (soweit mein Verständnis) ist da nichts genaueres definiert. In der Beschreibung steht: "Img: memory for the image (header and image data)prepared by the called application".
Aber wie kann ich nur den Speicher übergeben?

Ein Array ist ein Speicher! void * wird meist verwendet wenn der Datentyp variabel ist oder komplex, also ein Header und anderen Daten folgen. Ob da immer 16 Bit pro Pixel sind ist noch fraglich, das hängt von der Hardware ab. Bei manchen Grabber Karten hängt das ganz einfach vom Bildformat ab das man im Treiber zuvor konfiguriert hat. Das kann also durchaus einmal ein Byte sein, ein anderes mal ein 16 bit Wort und manchmal auch ein 4 byte Float. Auch erlauben viele Framegrabber um das Bildformat einzustellen, so dass die Anzahl Pixel ebenfalls variabel sein kann.

Wenn Du denn sicher bist dass es ein 16 bit/Pixel Fromat ist, und es immer genau 320 * 240 Pixel sind, dann musst Du also ein Byte Array mit 155328 Elementen initialisieren und and den DLL Parameter übergeben. Danach kommt der interessante Teil, und das ist die Daten aus dem Byte-Array herauszuklauben. Man muss dann die ersten 1728 Bytes als Header herauskopieren und in der von der Library beschriebenen Weise interpretieren und dann die restlichen Bytes in eine 2 dimensionales 16 bit Array umwandlen. Grundsätzlich nicht sehr kompliziert aber bevor das alles gut funktioniert wirst Du noch viele Versuche machen müssen. Viel Vergnügen dabei!! Big Grin


RE: DLL einbinden mit "void * func" - kaiman - 17.10.2011 08:26

Ok, ich versteh jetzt was du meinst. Ich kann natürlich nicht genau sagen, wie die Daten von der Kamera kommen, ich weiß nur die Größe des Speichers die ein Bild benötigt. Ich habe C++ Code, in dem nur Speicher reserviert wird, es wird aber keine direkte Variable erzeugt, in die die Pixelwerte geschrieben werden. Ich müsste doch eigentlich Speicher der Bildgröße+Header allozieren und dann die Daten direkt aus dem Speicher ziehen. Womit kann ich denn in LV einfach nur Speicher einer bestimnmten Größe allozieren? Mit den Memory Control VIs geht das nicht oder? Oder versteh ich die nur nicht?

Vielen Dank für deine Unterstützung!


RE: DLL einbinden mit "void * func" - rolfk - 17.10.2011 08:38

(17.10.2011 08:26 )kaiman schrieb:  Ok, ich versteh jetzt was du meinst. Ich kann natürlich nicht genau sagen, wie die Daten von der Kamera kommen, ich weiß nur die Größe des Speichers die ein Bild benötigt. Ich habe C++ Code, in dem nur Speicher reserviert wird, es wird aber keine direkte Variable erzeugt, in die die Pixelwerte geschrieben werden. Ich müsste doch eigentlich Speicher der Bildgröße+Header allozieren und dann die Daten direkt aus dem Speicher ziehen. Womit kann ich denn in LV einfach nur Speicher einer bestimnmten Größe allozieren? Mit den Memory Control VIs geht das nicht oder? Oder versteh ich die nur nicht?

Vielen Dank für deine Unterstützung!

Wie wäre es mit Initialize Array? Wahrscheinlich zu einfach?


RE: DLL einbinden mit "void * func" - kaiman - 17.10.2011 09:00

Naja, damit habe ich es schon probiert.
Die Frage ist ja, ob ich der DLL überhaupt ein Array übergeben muss, oder nicht. Wenn es kein Array sein soll/darf sondern nur der Zeiger auf den Speicher wo das Bild hin geschrieben werden soll, wie könnte ich das dann anstellen? Kann ich eine Referenz o.ä. auf den Speicher in LV an die DLL übergeben und mir dann aus diesem Speicher die Pixelwerte raus ziehen?Wacko


RE: DLL einbinden mit "void * func" - rolfk - 17.10.2011 14:08

(17.10.2011 09:00 )kaiman schrieb:  Naja, damit habe ich es schon probiert.
Die Frage ist ja, ob ich der DLL überhaupt ein Array übergeben muss, oder nicht. Wenn es kein Array sein soll/darf sondern nur der Zeiger auf den Speicher wo das Bild hin geschrieben werden soll, wie könnte ich das dann anstellen? Kann ich eine Referenz o.ä. auf den Speicher in LV an die DLL übergeben und mir dann aus diesem Speicher die Pixelwerte raus ziehen?Wacko

Huuuh??? Darf ich Dich auf diese quote hinweisen?

Zitat:In der Beschreibung steht nur, dass ich für Img ausreichend Speicher allozieren muss mit einer Größe von (1728 + 153600)bytes für ein 320*240 Bild. Jedes Pixel hat 16bit, weshalb also jedes Pixel 2 byte braucht. Da aber ja mit "void * Img" nur der Zeiger auf den allozierten Speicher übergeben wird (soweit mein Verständnis) ist da nichts genaueres definiert. In der Beschreibung steht: "Img: memory for the image (header and image data)prepared by the called application".

Das sagt eindeutig dass die Applikation den Speicher allozieren muss. Was Du in LabVIEW mit Initiliaze Array auch machen kannst. Ob dieses Array den nun als Pointer an die DLL übergeben werden kann oder nicht, wissen wir nicht. Du hast nähmlich noch immer nicht mal ein Stück Header gepostet, noch mehr als ein kurzes Zitat aus dem Manual. Am besten wäre nÄturlich wenn Du ein C Beispielprogramm hast in dem man genau sehen kann was den getan werden muss.

Aber alles in allem ist zu dem ganzen Thema eines zu sagen: Das ist nich LabVIEw Point and Click! Man muss einiges an C Programmierung verstehen um ein Framegrabber gut in LabVIEw integreieren zu können, ob man da jetzt in C eine Wrapper-DLL programmiert oder das direkt im LabVIEW Diagram versucht. Letzteres braucht effektiv fast immer sogar mehr C Programmierkenntnisse als in C eine Wrapper DLL zu programmiern.