LabVIEWForum.de
C-DLL, Speicherüberschreibung, Arraygröße - 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: C-DLL, Speicherüberschreibung, Arraygröße (/Thread-C-DLL-Speicherueberschreibung-Arraygroesse)

Seiten: 1 2


C-DLL, Speicherüberschreibung, Arraygröße - Pacco di Bango - 02.02.2009 14:18

Hallo,

ich arbeite gerade daran, externen C-Code als DLL über den Call-Library-Function-Node in LV einzubinden.
Nun habe ich ein Problem mit Speicherüberschreibung.
Ich übergebe ein Array der Länge n an den CLFN, die DLL macht ein Array der Länge 2*n daraus und LV stürzt ab.
Leider kann ich das Ausgabe-Array im C-Code nicht allokieren, da (LabVIEW dann zwar nicht mehr abstürzt aber) das C-Programm nicht mehr das macht, was es soll.
Der Quellcode stammt nicht von mir, sondern ist aus den Numerical-Recipes für C übernommen. Weil ich noch nicht wirklich programmiert habe, verstehe ich diese Routine auch nicht völlig. An sich (unabhängig von LV) funktioniert sie aber.

Nun meine Frage:
Kann ich das Problem innerhalb von LV lösen, ohne die C-Routine zu ändern?!

"Build Array" nützt nichts und
"Initialize Array" kann ich aufgrund unterschiedlicher Datentypen...

("Array element conflict: You have connected an array data type to its element data type. This type conflict may be resolved by indexing the array to access individual elements of the array. Check for a tunnel on a loop that has indexing incorrectly enabled.
The type of the source is 1-D array of
single [32-bit real (~6 digit precision)].
The type of the sink is double [64-bit real (~15 digit precision)].")

...nicht verbinden.

Hoffe auf Hilfe...

Gruß
Pacco


C-DLL, Speicherüberschreibung, Arraygröße - IchSelbst - 02.02.2009 16:42

' schrieb:Ich übergebe ein Array der Länge n an den CLFN, die DLL macht ein Array der Länge 2*n daraus und LV stürzt ab.
Täte ich auch.

Wie übergibst du denn das Array an C: "Zeiger auf Daten" und "Anzahl" oder "Zeiger auf Handle"?

Wie kommen denn die Daten zurück: Im selben (<=!) Parameter (also MyFkt(float **DataInOut) oder so) oder in einem zweiten (aslo MyFkt(const float *DataIn, float*DataOut)).

Zitat:"Initialize Array" kann ich aufgrund unterschiedlicher Datentypen...
Zum Datenkontertieren gibt es ein Element, das z.B. aus single double macht.


C-DLL, Speicherüberschreibung, Arraygröße - jg - 02.02.2009 17:58

Deine Infos sind etwas dünn und verwirrend.

Folgender Vorschlag:
Lad mal VI & dll hoch und poste des gesamten Sourcecode deiner c-Funktion (entweder hochladen oder hier als "QUOTE" reinschreiben).

Und noch eine Rückfrage:
Was meinst du mit:
Zitat:Ich übergebe ein Array der Länge n an den CLFN, die DLL macht ein Array der Länge 2*n daraus und LV stürzt ab.
Willst du wirklich in C die Anzahl der Elemente des Arrays verdoppeln? Davon würde ich aber dringend abraten. Da kommen sich der Speichermanager von LabVIEW und von C garantiert in die Quere! Kein Wunder, dass du was von Absturz schreibst.

Gruß, Jens


C-DLL, Speicherüberschreibung, Arraygröße - Pacco di Bango - 02.02.2009 18:22

' schrieb:Täte ich auch.

Wie übergibst du denn das Array an C: "Zeiger auf Daten" und "Anzahl" oder "Zeiger auf Handle"?

Wie kommen denn die Daten zurück: Im selben (<=!) Parameter (also MyFkt(float **DataInOut) oder so) oder in einem zweiten (aslo MyFkt(const float *DataIn, float*DataOut)).

Zum Datenkontertieren gibt es ein Element, das z.B. aus single double macht.


meine Exportfunktion lautet:

__declspec(dllexport) void correl(float data1[], float data2[], unsigned long n, float ans[]);

n ist die Anzahl der Samples.
data1 bekommt ein Sinussignal (n Samples).
data2 bekommt ein Rechtecksignal (n Samples).
ans liefert die Kreuzkorrelation beider Signale (2*n Samples).

Hier der Code

[code]#define NRANSI
#include "nrutil.h"

void correl(float data1[], float data2[], unsigned long n, float ans[])
{


C-DLL, Speicherüberschreibung, Arraygröße - IchSelbst - 02.02.2009 19:03

' schrieb:meine Exportfunktion lautet:
Kannst du auch ein VI hier einstellen, das einen DLL-Knoten enthält, der diese Funktion aufruft?


C-DLL, Speicherüberschreibung, Arraygröße - rolfk - 02.02.2009 19:33

' schrieb:meine Exportfunktion lautet:

__declspec(dllexport) void correl(float data1[], float data2[], unsigned long n, float ans[]);

n ist die Anzahl der Samples.
data1 bekommt ein Sinussignal (n Samples).
data2 bekommt ein Rechtecksignal (n Samples).
ans liefert die Kreuzkorrelation beider Signale (2*n Samples).

Das scheint mir ziemlich eindeutig. Die Funktion hat 4 Parameter. Parameter 1 und 2 sind Arrays die Du in LabVIEW generierst und an die Funktion als Array C Datenpointer von Typ float (LabVIEW Single Precision Float) übergibts. Parameter 3 ist ganz einfach ein 32 Bit unsigned Integer der als Value übergeben wird. Der letzte Parameter ist auch wieder dasselbe als die ersten zwei. Hier musst Du aber in LabVIEW mit Initialize Array ein Array von 2 * n Elementen erzeugen und an das Terminal verbinden.

Das ist alles.

Übrigens hat LabVIEW auch Korrelationsfunktionen die ebenfalls in einer DLL implementiert sind. Dort wird aber nicht einfach der Code aus Numerical-Recipes für C genommen sondern nach den Funktionen der Intel Math Kernel Library gelinkt. Diese Library ist ausführlicher (mehr Funktionen), genauer und schneller (spezifische Intel CPU Optimalisierungen werden benützt) als Numerical-Recipes für C und in gewissen Fällen auch korrekter. Die Numerical-Recipes für C Routinen sind grundsätzlich nicht schlecht aber das Ziel war nicht um die Beste numerische Library zu machen sondern zu zeigen wie man numerische Berechnungen in C grundsätzlich auf eine elegante und gut lesbare Weise machen kann. Die Detailimplementierung von speziellen Randbedingungen und Optimalisierungen ist diesem Ziel aber oft entgegengesetzt.

Rolf Kalbermatter


C-DLL, Speicherüberschreibung, Arraygröße - Pacco di Bango - 02.02.2009 22:17

' schrieb:Der letzte Parameter ist auch wieder dasselbe als die ersten zwei. Hier musst Du aber in LabVIEW mit Initialize Array ein Array von 2 * n Elementen erzeugen und an das Terminal verbinden.

Das ist alles.

Und wie mache ich das?! Ich müsste doch noch Daten konvertieren, da die Verbindung ungültig ist.

("Array element conflict: You have connected an array data type to its element data type. This type conflict may be resolved by indexing the array to access individual elements of the array. Check for a tunnel on a loop that has indexing incorrectly enabled.
The type of the source is 1-D array of
single [32-bit real (~6 digit precision)].
The type of the sink is double [64-bit real (~15 digit precision)].")

Hab noch nicht so viel Erfahrung.

Aber Danke erstmal für den Tipp mit "Intel Math Kernel Library".


C-DLL, Speicherüberschreibung, Arraygröße - jg - 02.02.2009 22:30

' schrieb:Und wie mache ich das?! Ich müsste doch noch Daten konvertieren, da die Verbindung ungültig ist.

("Array element conflict: You have connected an array data type to its element data type. This type conflict may be resolved by indexing the array to access individual elements of the array. Check for a tunnel on a loop that has indexing incorrectly enabled.
The type of the source is 1-D array of
single [32-bit real (~6 digit precision)].
The type of the sink is double [64-bit real (~15 digit precision)].")

Hab noch nicht so viel Erfahrung.

Aber Danke erstmal für den Tipp mit "Intel Math Kernel Library".
Es bleibt beim Raten... 2x haben wir dich gebeten, auch das VI hochzuladen, mit dem du die Funktion aufrufen willst.Wall

Schauen wir mal, ob ich trotz defekter Kristallkugel richtig rate:
Ich nehme mal an, dass du probierst, für das "Rückgabe-Array" in LabVIEW per "Initialize Array" Speicher zu reservieren und beim Eingang "element" einfach auf "Create->Constant" geklickt hast. Damit wird dir eine Konstante vom Datentyp "double" erzeugt. Umstellen auf Datentyp "single geht über "Rechter Mausklick->" und dann siehe Screenshot:
[attachment=16555]

Gruß, Jens


C-DLL, Speicherüberschreibung, Arraygröße - Pacco di Bango - 02.02.2009 23:21

' schrieb:Es bleibt beim Raten... 2x haben wir dich gebeten, auch das VI hochzuladen, mit dem du die Funktion aufrufen willst.Wall

Schauen wir mal, ob ich trotz defekter Kristallkugel richtig rate:
Ich nehme mal an, dass du probierst, für das "Rückgabe-Array" in LabVIEW per "Initialize Array" Speicher zu reservieren und beim Eingang "element" einfach auf "Create->Constant" geklickt hast. Damit wird dir eine Konstante vom Datentyp "double" erzeugt. Umstellen auf Datentyp "single geht über "Rechter Mausklick->" und dann siehe Screenshot:
[attachment=44215:Image01.png]

Gruß, Jens

Achja... sorry!
Kann leider erst morgen mit komplettem C-Code, DLL und VI dienen.
Bin gespannt. Also erstmal gute Nacht ...


Pacco


C-DLL, Speicherüberschreibung, Arraygröße - rolfk - 03.02.2009 08:31

' schrieb:Und wie mache ich das?! Ich müsste doch noch Daten konvertieren, da die Verbindung ungültig ist.

("Array element conflict: You have connected an array data type to its element data type. This type conflict may be resolved by indexing the array to access individual elements of the array. Check for a tunnel on a loop that has indexing incorrectly enabled.
The type of the source is 1-D array of
single [32-bit real (~6 digit precision)].
The type of the sink is double [64-bit real (~15 digit precision)].")

Hab noch nicht so viel Erfahrung.

Aber Danke erstmal für den Tipp mit "Intel Math Kernel Library".

Eine andere Kristallkugelraterei. Die Differenz zwischen Double und Single sollte keinen Fehler geben, nur eine Performancekilling Coercion.
Aber Du hast wohl den Parameter in der Call Library Node nicht als Array definiert sondern nur als Double Skalar Fliesskommazahl, eventuel noch passed by Reference. Das sieht in C Syntax tatsächlich gleich aus da
float *var genau dasselbe ist with float var[] aber ist für LabVIEW absolut nicht dasselbe. Das eine ist ein Pointer auf einen einzelne Fliesskommazahl, das andere ist ein Array. Und da LabVIEW nicht einfach mit Pointern arbeitet sondern mit expliziten Datentypen ist das ein gewaltiger, sprich inkompatibler Unterschied.

Rolf Kalbermatter