14.10.2011, 13:42
Beitrag #1
|
kaiman
LVF-Gelegenheitsschreiber
Beiträge: 146
Registriert seit: Dec 2008
7.1.1, 2011
2007
EN
28***
Deutschland
|
DLL einbinden mit "void * func"
Moin liebe Forumuser,
ich versuche mich gerade zum ersten mal daran eine dll einzubinden - mehr oder weniger erfolgreich.
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,
Kai
|
|
|
14.10.2011, 13:56
Beitrag #2
|
rolfk
LVF-Guru
Beiträge: 2.305
Registriert seit: Jun 2007
alle seit 6.0
1992
EN
2901GG
Niederlande
|
RE: DLL einbinden mit "void * func"
(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.
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,
Kai
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.
|
|
|
14.10.2011, 14:31
Beitrag #3
|
kaiman
LVF-Gelegenheitsschreiber
Beiträge: 146
Registriert seit: Dec 2008
7.1.1, 2011
2007
EN
28***
Deutschland
|
RE: DLL einbinden mit "void * func"
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.
|
|
|
14.10.2011, 14:57
Beitrag #4
|
rolfk
LVF-Guru
Beiträge: 2.305
Registriert seit: Jun 2007
alle seit 6.0
1992
EN
2901GG
Niederlande
|
RE: DLL einbinden mit "void * func"
(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.
|
|
|
14.10.2011, 15:23
Beitrag #5
|
|
|
14.10.2011, 17:00
Beitrag #6
|
rolfk
LVF-Guru
Beiträge: 2.305
Registriert seit: Jun 2007
alle seit 6.0
1992
EN
2901GG
Niederlande
|
RE: DLL einbinden mit "void * func"
(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!!
|
|
|
17.10.2011, 08:26
Beitrag #7
|
|
|
17.10.2011, 08:38
Beitrag #8
|
|
|
17.10.2011, 09:00
Beitrag #9
|
|
|
17.10.2011, 14:08
|
|
|
| |