02.02.2009, 14:18
Beitrag #1
|
Pacco di Bango
LVF-Neueinsteiger
Beiträge: 7
Registriert seit: Feb 2009
8.5.1
2008
de_en
17491
Deutschland
|
C-DLL, Speicherüberschreibung, Arraygröße
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
Der Fehler sitzt immer vor der Maschine.
[altes Schneidersprichwort]
|
|
|
02.02.2009, 16:42
Beitrag #2
|
IchSelbst
LVF-Guru
Beiträge: 3.696
Registriert seit: Feb 2005
11, 14, 15, 17, 18
-
DE
97437
Deutschland
|
C-DLL, Speicherüberschreibung, Arraygröße
' 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.
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
|
|
|
02.02.2009, 17:58
Beitrag #3
|
jg
CLA & CLED
Beiträge: 15.864
Registriert seit: Jun 2005
20xx / 8.x
1999
EN
Franken...
Deutschland
|
C-DLL, Speicherüberschreibung, Arraygröße
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
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.
|
|
|
02.02.2009, 18:22
Beitrag #4
|
Pacco di Bango
LVF-Neueinsteiger
Beiträge: 7
Registriert seit: Feb 2009
8.5.1
2008
de_en
17491
Deutschland
|
C-DLL, Speicherüberschreibung, Arraygröße
' 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[])
{
Der Fehler sitzt immer vor der Maschine.
[altes Schneidersprichwort]
|
|
|
02.02.2009, 19:03
Beitrag #5
|
IchSelbst
LVF-Guru
Beiträge: 3.696
Registriert seit: Feb 2005
11, 14, 15, 17, 18
-
DE
97437
Deutschland
|
C-DLL, Speicherüberschreibung, Arraygröße
' schrieb:meine Exportfunktion lautet:
Kannst du auch ein VI hier einstellen, das einen DLL-Knoten enthält, der diese Funktion aufruft?
Jeder, der zur wahren Erkenntnis hindurchdringen will, muss den Berg Schwierigkeit alleine erklimmen (Helen Keller).
|
|
|
02.02.2009, 22:17
Beitrag #7
|
Pacco di Bango
LVF-Neueinsteiger
Beiträge: 7
Registriert seit: Feb 2009
8.5.1
2008
de_en
17491
Deutschland
|
C-DLL, Speicherüberschreibung, Arraygröße
' 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".
Der Fehler sitzt immer vor der Maschine.
[altes Schneidersprichwort]
|
|
|
02.02.2009, 22:30
(Dieser Beitrag wurde zuletzt bearbeitet: 02.02.2009 22:30 von jg.)
Beitrag #8
|
jg
CLA & CLED
Beiträge: 15.864
Registriert seit: Jun 2005
20xx / 8.x
1999
EN
Franken...
Deutschland
|
C-DLL, Speicherüberschreibung, Arraygröße
' 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.
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:
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.
|
|
|
02.02.2009, 23:21
Beitrag #9
|
Pacco di Bango
LVF-Neueinsteiger
Beiträge: 7
Registriert seit: Feb 2009
8.5.1
2008
de_en
17491
Deutschland
|
C-DLL, Speicherüberschreibung, Arraygröße
' schrieb:Es bleibt beim Raten... 2x haben wir dich gebeten, auch das VI hochzuladen, mit dem du die Funktion aufrufen willst.
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
Der Fehler sitzt immer vor der Maschine.
[altes Schneidersprichwort]
|
|
|
03.02.2009, 08:31
(Dieser Beitrag wurde zuletzt bearbeitet: 03.02.2009 08:32 von rolfk.)
|
rolfk
LVF-Guru
Beiträge: 2.305
Registriert seit: Jun 2007
alle seit 6.0
1992
EN
2901GG
Niederlande
|
C-DLL, Speicherüberschreibung, Arraygröße
' 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
|
|
|
| |