' schrieb:
Code:
unsigned int GetData(double **X, double **Y);
Das ist wie Du schon richtig erkannt hast jeweils ein Pointer auf ein Array.
Zitat:Typ: Array
Datentyp: 8-Byte-Double
Dimension: 1
Array-Format: Array-Handle
An die Ein- und Ausgänge des LabVIEW-Blocks habe ich zum Testen Bedien- bzw. Anzeigeelemente gehängt.
Das geht leider so nicht. LabVIEW Arrays sind speziale LabVIEW Handles und müssen deshalb auch mit LabVIEW Funktionen alloziert und dealloziert werden. Da kannst Du nicht einen Speicherbereich der von einer DLL einfach so angelegt wird hineinwürgen. Auch die Pointer to Handle Option ist hier keine Lösung.
Zitat:Das Problem ist, dass LabVIEW nach dem Aufruf entweder den Dialog "Nicht genügend Speicher zum Abschließen dieser Operation" anzeigt, oder direkt nach der Ausführung abstürzt. (Unabhängig davon, ob ich die Funktion zum Freigeben des Speichers aufrufe oder nicht.) Ich denke mal, da kommen sich die DLL und der Speichermanager in die Quere, oder?
Das ist logisch und Deine Vermutung, dass das mit Speichermanagement zu tun hat trifft hier im Prinzip zu. Die DLL alloziert einen Speicher durch Aufruf von alloc() oder anverwandten Freunden und Du gibts Sie an LabVIEW zurück und sagst ihm schau das ist ein Arrayhandle. Irgenwann versucht LabVIEW das vermeintliche Arrayhandle anzusprechen oder auf seine eigene Weise zu deallozieren und läuft schrecklich ins Nirvana.
Zitat:Tja jedenfalls weiß ich nicht genau wie ich die Funktion behandeln soll, sodass keine Speicherkonflikte entstehen.
Da hängt davon ab was Du mit diesem Array in LabVIEW tun können musst. Grundsätzlich kannst Du diesen Arraypointer ganz einfach als Pointersized Integer behandeln (in Deinem Fall konfigurierst Du den Parameter als Pointersized Integer, Pass Pointer to Value). Dann bekommst Du in LabVIEW einen 32/64 Bit-Integer der den Pointer auf das Array representiert. Musst Du diesen Pointer "nur" an andere C Funktionen mittels Call Library Node übergeben, ist das Problem schon gelöst.
Willst Du dagegen die Daten im Array in LabVIEW auch noch lesen können, kommst Du nicht darum herum die entsprechende Information aus diesem Pointer herauszukopieren. Das kann man tun indem man die LabVIEW C Funktion MoveBlock() mittels Call Library Node aufruft.
Das geht ungefähr so:
Library Name: LabVIEW
Function Name: MoveBlock
Calling Convention: C
return value: void
1. Parameter: source, pointersized integer (Dein Pointer von Deiner Funktion)
2. Parameter: dest, Arraytype Deiner Wahl passed als C Array Pointer
3. Parameter: length, int32, passed as value, hier übergibst Du die Anzahl Byte die kopiert werden müssen, also Anzahl Arrayelemente * Arrayelement size in Bytes (8 für double Array)
Last but not least: Pointer die irgendwann angelegt wurden sollten auch wieder dealloziert werden. Deine DLL sollte dazu entsprechende Funktionen exportieren oder die Dokumentation sollte erwähnen, welche (OS-)Funktion dazu verwendet werden sollte. Verwendung von free() ist jedenfalls keine Option, da die DLL und der Aufrufer zwei verschiedene Versionen der C Runtime Library verwenden könnten und dann ist ein Speicherbereich, angelegt in der einen Runtime, undefiniert innerhalb der anderen.
Rolf Kalbermatter
CIT Engineering Netherlands