LabVIEWForum.de - LabVIEW: Absturz nach externem Code-Aufruf

LabVIEWForum.de

Normale Version: LabVIEW: Absturz nach externem Code-Aufruf
Du siehst gerade eine vereinfachte Darstellung unserer Inhalte. Normale Ansicht mit richtiger Formatierung.
Seiten: 1 2 3
Dann debug doch mal, wenn du die Daten von LabVIEW nimmst....
Hast du dann schon nichts am Eingang oder gehen die Daten erst am Ausgang verloren.....
darum würde ich ersteinmal debuggen...
<!--quoteo(post=36206:date=10.09.2007 , 16:39:11:name=<<oenk>>)--><div class='quotetop'>ZITAT(<<oenk>> @ 10.09.2007 , 16:39:11) [url=index.php?act=findpost&pid=36206][/url]</div><div class='quotemain'><!--quotec-->Dann debug doch mal, wenn du die Daten von LabVIEW nimmst....
Hast du dann schon nichts am Eingang oder gehen die Daten erst am Ausgang verloren.....
darum würde ich ersteinmal debuggen...[/quote]

Wenn du mir sagst wie ich debuggen kann, wenn ich das Skript über ein CIN ausführe. Ich verwende keine DLL. Und das Skript wurde vorher in eine lsb Datei konvertiert. Ich kann also keine Breakpoints setzen. Aber wenn es eine Möglichkeit gibt den Code zu debuggen, wäre ich froh wenn du mir sagen könntest wie.
' schrieb:NumericArrayResize(uB, 2L, (UHandle*)&Array, PixelX * PixelY))
Wenn's mit f64, was sein muss, nicht funktioniert, aber mit uB, was aber zu klein ist - würde ich folgendes probieren: "NumericArrayResize(uB, 2L, (UHandle*)&Array, PixelX*8 * PixelY*8))". Ein uB ist wohl ein "unsigned byte" was von der Größe ein Achtel f64 ist. Du nimmst also beim Anfordern von Speicher anstelle der richtigen Basisgröße einfach eine "erhöhte Anzahl von Werten" angeben - dann ist die Anzahl der erforderlichen Speicherbytes auch wieder richtig. Ohne Gewähr.

Außerdem ist es bestimmt nicht falsch, wenn du die Wertzuweisungen auf DimSize[] beibehälst. Ich würde die beibehalten oder aus der struct-Definition entfernen.
' schrieb:Wenn's mit f64, was sein muss, nicht funktioniert, aber mit uB, was aber zu klein ist - würde ich folgendes probieren: "NumericArrayResize(uB, 2L, (UHandle*)&Array, PixelX*8 * PixelY*8))". Ein uB ist wohl ein "unsigned byte" was von der Größe ein Achtel f64 ist. Du nimmst also beim Anfordern von Speicher anstelle der richtigen Basisgröße einfach eine "erhöhte Anzahl von Werten" angeben - dann ist die Anzahl der erforderlichen Speicherbytes auch wieder richtig. Ohne Gewähr.

Außerdem ist es bestimmt nicht falsch, wenn du die Wertzuweisungen auf DimSize[] beibehälst. Ich würde die beibehalten oder aus der struct-Definition entfernen.

In der Verbindung mit NumericArrayResize funktioniert ->dimSizes[...] nicht mehr. Wenn ich diese Zuweisung raus nehme wird das Skript durchlaufen. Aber dein Tip mit PixelX * 8 * PixelY *8 ist ne gute Idee. Ich frage mich nur wo der typeCode f64 zu finden ist. In meinem LabVIEW ® Code Interface Reference Manual ist der gar nicht genannt. Bei mir stehen nur diese:

Describes the data type for the array that
you want to resize. The header file
extcode.h defines the following
constants for this argument
iB Data is an array of signed 8-bit
integers.
iW is an array of signed 16-bit integers.
iL Data is an array of signed 32-bit
integers.
uB Data is an array of unsigned 8-bit
integers.
uW Data is an array of unsigned 16-bit
integers.
uL Data is an array of unsigned 32-bit
integers.
fS Data is an array of single-precision
(32-bit) numbers.
fD Data is an array of double-precision
(64-bit) numbers.
fX Data is an array of extendedprecision
numbers.
cS Data is an array of single-precision
complex numbers.
cD Data is an array of double-precision
complex numbers.
cX Data is an array of extendedprecision
complex numbers.
' schrieb:Ich frage mich nur wo der typeCode f64 zu finden ist.
Nimmst du fD: "fD Data is an array of double-precision (64-bit) numbers."

' schrieb:In der Verbindung mit NumericArrayResize funktioniert ->dimSizes[...] nicht mehr. Wenn ich diese Zuweisung raus nehme wird das Skript durchlaufen.
Brauchst du das dimSize[] überhaupt für irgendwas? Wenn nicht würde ich das aus dem Struct heraus nehmen - und eigenlich gleich das ganze Struct entfernen und nur ein Array nehmen.
Jupp, kann ich dir sagen...
In 7.0 und 7.1 ging es so

guckst du hier: http://www.ni.com/pdf/manuals/370109b.pdf (Seite 3-22 oder 81 im AcrobatReader)

ich denke in 8.20 wird es wohl ähnlich gehen

viel Erfolg und viele Gruesse

Christian
' schrieb:Habs mal mit der NumericArrayResize() Funktion versucht. Den typeCode f64 kennt die Funktion schonmal nicht. Habs dann so versucht:
if(err = NumericArrayResize(uB, 2, (UHandle*) &Array, PixelX * PixelY))
goto release
Das hat er dann auch geschluckt. Mein Skript sieht nun also folgendermaßen aus:

Das geht natürlich ganz fest falsch. Der f64 hatte ich leider falsch im Gedächtnis. Muss natürlich fD sein. Schau doch auch mal ganz einfach im External Code Reference Manual nach (ältere LabVIEWs Help->Search LabVIEW Bookshelf und dann da der Link External Code Reference, neuere LabVIEWs leider nicht mehr als PDF Dokument sondern nicht so praktisch in der ganzen Hilfe verpackt:
VI and Function Reference->Connectivity VIs and Functions-> Libraries & Executables->Code Interface Node Functions).

Ohne diese Referenz ist die Programmierung von DLLs (oder CINs) welche Gebrauch machen von den LabVIEW Manager Funktionen praktisch aussichtslos.

Der erste Parameter bei NumericArrayResize gibt den Elementdatentypen an den ein einzelnes Element im Array haben soll. Wenn Du da uB machst nimmt die Funktion einfach mal an dass Du da ein Bytearray hast. Das Ganze kannst Du zwar wieder tricksen indem Du die Anzahl Elemente mit 8 (double byte size) ^ Anzahl Dimensionen multiplizierst, aber das hat potentiel wieder Alignmentprobleme, da LabVIEW auf einigen Platformen spezielles Elementalignment vornimmt. NumericArrayResize trägt dem alles Rechnung.

Und Du füllst zwar das Array mit Daten vergisst aber jetzt um im Array auch noch zu vermelden wieviele Daten Du da reingepackt hast. Der LabVIEW Memory Manager will dass Du Arrays sauber mit seinen Funktionen anlegst, in Grösse veränderst und wieder freigibst, das LabVIEW Diagram verwendet aber die dimSizes im Array um zu wissen, ob und wieviel Daten da denn sind. Beides ist unabdingbar nötig, dass es korrekt funktioniert.

Also füg doch noch mal nach dem Datenkopieren soetwas ein wie:

(*Array)->dimSize[0] = PixelX;
(*Array)->dimSize[1] = PixelY;

oder vielleicht auch umgekehrt. Bei zweidimensionalen Arrays weiss ich das nie so genauRolleyes

Rolf Kalbermatter
' schrieb:Brauchst du das dimSize[] überhaupt für irgendwas? Wenn nicht würde ich das aus dem Struct heraus nehmen - und eigenlich gleich das ganze Struct entfernen und nur ein Array nehmen.

Ja die braucht LabVIEW ganz eindeutig. Wenn es eine DLL wäre könntest Du wählen ob Du entweder einen Native LabVIEW Datentyp an die Funktion übergeben willst oder mehr etwas in der Art und Weise von "normalen" C Datentypen (ist noch diskutabel was ein normaler 2D Array in C ist). Bei LabVIEW Native Datentypen musst Du dann auch die LabVIEW Memory Manager Funktionen verwenden um daran etwas zu ändern. Bei C Datentypen muss der Aufrufer, also hier das LabVIEW Diagram, allen benötigten Speicher für eventuelle Parameter vor dem Aufruf bereitstellen. Beides hat so seine Vor- und Nachteile.

Bei einem CIN hast Du aber diese Wahl nicht. Da ist nur ein LabVIEW Native Datentyp möglich.

Rolf Kalbermatter
' schrieb:Ja die braucht LabVIEW ganz eindeutig.
Hätte ich mir fast denken können. Hab' ich mittlerweile auch so nachgelesen. Im von <<oenk>> verlinkten Dokument steht ja genau das als Quellcode drinnen, was abrissbirne machen will.
' schrieb:Hätte ich mir fast denken können. Hab' ich mittlerweile auch so nachgelesen. Im von <<oenk>> verlinkten Dokument steht ja genau das als Quellcode drinnen, was abrissbirne machen will.

Als erstes möchte ich mich bei euch für eure Unterstützung danken. Ich bin ein kleines Stückchen weitergekommen und ohne eure Anregungen, hätte es entweder noch lange gedauert, oder aber ich hätte irgendwann aufgegeben. Hab nun ein Skript, dass mir Daten von der Kamera in einen Puffer speichert. LabVIEW bekommt mittels eines Pointers Wert für Wert übertragen. Das ganze Funktioniert auch und ich bekomme in meinem Intensitätsgraphen ein Image. Nur leider hat das Bild nix mit dem von der Thermokamera aufgenommenen gleich. Zum besseren Verständnis hab ich mal ein Screenshot hochgeladen und den Quellcode gibts jetzt:

#include "extcode.h"
#include <windowsh>
#include <mil.h>

#define PixelX 320
#define PixelY 256

typedef struct{
int32 dimSizes[2];
float64 Numerisch[1];
} TD1;

typedef TD1 **TD1Hdl;

typedef char *STRING;

extern "C" MgErr CINRun(TD1Hdl Array);

MgErr CINRun(TD1Hdl Array)
{
MgErr = noErr;
STRING DCF_File = "D:\Dokumente...";

Mil_ID
MilApplication = M_NULL,
MilSystem = M_NULL,
MilDigitizer = M_NULL,
ImagBuffer[PixelX][PixelY];

float64 *ptrResultElement;
int cols, rows;

MilApplication = MappAlloc(M_DEFAULT, M_NULL);
MilSystem = MsysAlloc(M_SYSTEM_SOLIOS, M_DEFAULT, M_COMPLETE, M_NULL);
MilDigitizer = MdigAlloc(MilSystem, M_DEFAULT, DCF_File, M_DEFAULT, M_NULL);
ImageBuffer[PixelX][PixelY] = MbufAlloc2d(MilSystem, PixelX, PixelY, M_UNSIGNED+16, M_IMAGE + M_DISP + M_GRAB + M_PROC, M_NULL);

if(err = NumericArrayResize(fD, 2L, (UHandle*)&Array, PixelX * PixelY))
goto release;

(*Array)->dimSizes[0] = PixelX;
(*Array)->dimSizes[1] = PixelY;
ptrResultElement = (*Array)->Numerisch;

if(MappGetError(M_GLOBAL, M_NULL))
goto release;

MdigGrab(MilDigitizer, ImageBuffer[PixelX][PixelY]);
if(MappGetError(M_GLOBAL, M_NULL))
goto release;

for(cols = 0; cols < PixelY; cols++)
{
*ptrResultElement = 0;
for(rows = 0; rows < PixelX; rows++)
{
*ptrResultElement = ImageBuffer[rows][cols];
ptrElementResult++;
}
}

release:
MbufFree(ImageBuffer[PixelX][PixelY];
MdigFree(MilDigitizer);
MsysFree(MilSystem);
MappFree(MilApplication);

return err;
}
Seiten: 1 2 3
Referenz-URLs