INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.


Antwort schreiben 

ANTDKT3



Wenn dein Problem oder deine Frage geklärt worden ist, markiere den Beitrag als "Lösung",
indem du auf den "Lösung" Button rechts unter dem entsprechenden Beitrag klickst. Vielen Dank!

03.09.2008, 21:06 (Dieser Beitrag wurde zuletzt bearbeitet: 16.11.2008 09:43 von Dennis.Moser.)
Beitrag #1

masht Offline
LVF-Grünschnabel
*


Beiträge: 11
Registriert seit: Sep 2008

8.5
2007
de

1150
Oesterreich
ANTDKT3
Hallo,

ich versuche nun schon seit einiger zeit mit meinen nicht vorhandenen c++ kenntnissen das ANT (http://www.thisisant.com) unter LabVIEW nutzbar zu machen, aber leider ohne erfolg Sad

kurz zur beschreibung des problems - die dll des herstellers benötigt als parameter einen zeiger auf eine callbackfunktion - jedenfalls habe ich versucht, eine dll zu schreiben, die die dll und benötigten functionen der herstellerdll lädt und mir dann die daten an LabVIEW als userevent schickt (da gibts ein beispiel auf der ni seite: lvuserevent).

LabVIEW gibt mir dann den fehler 1097 beim aufruf der eventfunctionen zurück. habs natürlich gegoogelt und eine menge gefunden, was das sein könnte... aber ich find den fehler nicht.

falls jemand gut in c++ ist oder änliches probleme (callbackfunctionen bei dlls) gelöst hat und mir tipps geben könnte würde ich micht sehr freuen.

<strike>das vc++ projekt ist leider zu groß zum posten - kann aber unter http://www.unet.univie.ac.at/~a0302379/ant_sendevent.zip (4,7 MB [diese intellisense db..]) heruntergeladen werden.</strike>

Sonstige .zip  ant_sendevent.zip (Größe: 6,83 MB / Downloads: 298)


vielen, vielen dank im voraus
martin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
Anzeige
15.09.2008, 09:07 (Dieser Beitrag wurde zuletzt bearbeitet: 15.09.2008 09:12 von rolfk.)
Beitrag #2

rolfk Offline
LVF-Guru
*****


Beiträge: 2.302
Registriert seit: Jun 2007

alle seit 6.0
1992
EN

2901GG
Niederlande
ANTDKT3
' schrieb:Hallo,

ich versuche nun schon seit einiger zeit mit meinen nicht vorhandenen c++ kenntnissen das ANT (http://www.thisisant.com) unter LabVIEW nutzbar zu machen, aber leider ohne erfolg Sad

kurz zur beschreibung des problems - die dll des herstellers benötigt als parameter einen zeiger auf eine callbackfunktion - jedenfalls habe ich versucht, eine dll zu schreiben, die die dll und benötigten functionen der herstellerdll lädt und mir dann die daten an LabVIEW als userevent schickt (da gibts ein beispiel auf der ni seite: lvuserevent).

LabVIEW gibt mir dann den fehler 1097 beim aufruf der eventfunctionen zurück. habs natürlich gegoogelt und eine menge gefunden, was das sein könnte... aber ich find den fehler nicht.

falls jemand gut in c++ ist oder änliches probleme (callbackfunctionen bei dlls) gelöst hat und mir tipps geben könnte würde ich micht sehr freuen.

das vc++ projekt ist leider zu groß zum posten - kann aber unter http://www.unet.univie.ac.at/~a0302379/a...devent.zip (4,7 MB [diese intellisense db..]) heruntergeladen werden.

vielen, vielen dank im voraus
martin
H e r z l i c h e n G l ü c k w u n s c h !
L V F - T a s s e 2 0 0 8!
Bei dem von Dir geposteten Vorbild blick ich leider nicht durch. Mir scheint Du hast die Idee von Callbacks nach Userevents nicht sinnvoll aus dem heruntergeladenen Vorbild herauskristallisiert.

Du musst per Callback in Deiner DLL eine Registerfunction haben mit der von LabVIEW aus eine User Event Refnum an die DLL geben kannst die dann den zugehorigen Callback installiert und auch irgendwie die Zuweising Refnum<->Callback vornimmt. Wenn Deine Callback Funktion einen user data Parameter hat (meist einen uInt32 dem man zum Beispiel einen Pointer auf eine Struktur mit allen nötigen Informationen um sowohl allfällige extra Daten wie etwa Buffers aber auch die Informationen die nötig sind um den Zusammenhang zwischen der jeweiligen Refnum und der Instanz Deiner Callbackfunktion vermittlen zu können) kannst Du den verwenden.

Das klingt alles komplex und ist lästig zu tun? Ja aber da kommst Du einfach nicht darum herum. Selbst wenn Du von C aus C callbacks verwendest ist dies alles nicht grundsätzlich anders. Bei LabVIEW kommt einfach noch der extra Schritt mit der Umsetzung in ein Event hinzu.

Also was Du brauchst ist eine RegisterEvent Funktion die von Deiner DLL exportiert wird, die den LVUserEvent Refnum als Parameter bekommt. Diese Funktion legt einen Speicher an in dem sowohl alle benötigten Callbackbuffer Platz habe als auch diese LVUserEvent Refnum. Danach wird Deine Callbackfunktion installiert. Wenn die Callbackfunktion einen User Data Parameter hat den Du bei der Installation mitgeben kannst gibst Du dort den Pointer zum zuvor angelegten Speicher mit. Ansonsten musst Du diesen irgendwo in eine globale Variable schreiben und auch für jede neue Instanz Deiner Callbacks eine neue Globale und eine neue Callbackfunktion machen.

Die eigentliche Callbackfunktion holt sich den Datenpointer (entweder aus dem user data Parameter oder aus der entsprechenden Global) macht was immer nötig ist um die von der Callback mitgeteilten Parameter so schnell als möglich zu verarbeiten und sendet dann durch mittel von PostLVUserEvent das entsprechende Event an die LabVIEW Event Struktur, wobei Du die LVUserEvent Refnum verwendest die ebenfalls in dem Datenbuffer abgespeichert ist.

Wenn Du das Ganze echt perfekt machen willst gibst Du von der RegisterEvent Funktion auch noch den Pointer auf den angelegten Speicher als extra Parameter zurück und implementierst noch eine UnregisterEvent Funktion die diesen Pointer als Parameter bekommt, die entsprechenden Funktionen aufruft um die Callback zu deinstallieren und schliesslich auch noch den angelegten Speicher für den Buffer freigibt.

Rolf Kalbermatter

Rolf Kalbermatter
Technische Universität Delft, Dienst Elektronik und Mechanik
https://blog.kalbermatter.nl
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
16.11.2008, 09:01
Beitrag #3

masht Offline
LVF-Grünschnabel
*


Beiträge: 11
Registriert seit: Sep 2008

8.5
2007
de

1150
Oesterreich
ANTDKT3
hallo rolf, hallo LabVIEWforum,

wenn ich das richtig verstanden habe sollte das so laufen:

1.ich mache einen create user event --> übergebe die refnum meiner event funktion.
2. in meiner dll lege ich globale vars an z.b. für meinen char buffer.
3. in meiner event funktion kann ich dann mit postlvuserevent die daten an LabVIEW schicken.
4. die event funktion ist sogleich meine callback funktion - also übergebe ich die adresse an den aufrufer.

so habe ich das verstanden. nun - es funktioniert nicht, also muss ich das falsch verstanden haben. wichtig: laut herstellerbeschreibung sollte jedes mal, wenn die hw angesprochen wird automatisch die callbackfunktion und der buffer (von ant_assign*) genutzt werden.

tut mir leid, dass ich so lästig bin, aber ich kämpfe nun schon sehr lange mit diesem zeug herum und bin echt schon am verzweifeln. außerdem ist ant ja eine gute sache, und wenn das in LabVIEW funken würde wärs ja auch was...

bitte, helft mir - wenn mir das jemand erklären kann wäre ich sehr sehr sehr dankbar.

<div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>// antwrapper.cpp : Definiert die exportierten Funktionen für die DLL-Anwendung.
//

#include "stdafx.h"
#include "stdio.h"
#include "extcode.h" //LabVIEW inlcude

//Typendifinitionen für die ANT Funktionen
typedef BOOL (*ptreventfunction)(LVUserEventRef*);
typedef BOOL (*ptrresponsefunction)(LVUserEventRef*);

typedef void (*ANT_RESPONSE_POINTER)(ptrresponsefunction, UCHAR*);
typedef void (*ANT_EVENT_POINTER)(UCHAR, ptreventfunction, UCHAR*);

//Zeiger auf die ANT_Funktionen definieren
static ANT_RESPONSE_POINTER ANT_AssignResponseFunction = NULL;
static ANT_EVENT_POINTER ANT_AssignChannelEventFunction = NULL;

//ANT Buffer
UCHAR aucResponseBuffer[10];
UCHAR aucChannelEventBuffer[10];
char eventbuffer[10];

void PopulateStringHandle(LStrHandle lvStringHandle,char* stringData);
BOOL ANT_ChannelEventFunction(UCHAR ucChannel, UCHAR ucEvent);
BOOL ANT_ResponseFunction(UCHAR ucChannel, UCHAR ucMsgId);

static LVUserEventRef *eventref;
static LVUserEventRef *responseref;


extern "C" __declspec(dllexport) BOOL sendevent(LVUserEventRef *eventref)
{

strcpy((char*)&eventbuffer,(const char*)&aucChannelEventBuffer);
LStrHandle eventstringhandle;
//Allocate memory for a LabVIEW string handle using LabVIEW's
//memory manager functions.
eventstringhandle=(LStrHandle)DSNewHandle(sizeof(int32)+256*sizeof(uChar));
PopulateStringHandle(eventstringhandle,(char*)&eventbuffer);
PostLVUserEvent(*eventref, (void *)&eventstringhandle);
return TRUE;

}

extern "C" __declspec(dllexport) BOOL sendresponse(LVUserEventRef *responseref)
{

LStrHandle responsestringhandle;
//Allocate memory for a LabVIEW string handle using LabVIEW's
//memory manager functions.
responsestringhandle=(LStrHandle)DSNewHandle(sizeof(int32)+256*sizeof(uChar));
PopulateStringHandle(responsestringhandle,"Hallo");
PostLVUserEvent(*responseref, (void *)&responsestringhandle);
return TRUE;
}
extern "C" __declspec(dllexport) int ANT_DLL_Load(void)
{
HINSTANCE hANTdll = LoadLibraryA("ANT_DLL.dll");
if (hANTdll == NULL)

ANT_AssignResponseFunction = (ANT_RESPONSE_POINTER) GetProcAddress(hANTdll, "ANT_AssignResponseFunction");
ANT_AssignChannelEventFunction = (ANT_EVENT_POINTER) GetProcAddress(hANTdll, "ANT_AssignChannelEventFunction");

if (ANT_AssignResponseFunction == NULL)
return 0;
if (ANT_AssignChannelEventFunction == NULL)
return 0;
else
return 1;
}

/*//ChannelEventFunction
BOOL ANT_ChannelEventFunction(UCHAR ucChannel, UCHAR ucEvent)
{
LStrHandle eventstringhandle;
//Allocate memory for a LabVIEW string handle using LabVIEW's
//memory manager functions.
eventstringhandle=(LStrHandle)DSNewHandle(sizeof(int32)+256*sizeof(uChar));
PopulateStringHandle(eventstringhandle,"Hallo");
PostLVUserEvent(*eventref, (void *)&eventstringhandle);
return TRUE;
}

//ResponseFunction
BOOL ANT_ResponseFunction(UCHAR ucChannel, UCHAR ucMsgId)
{
LStrHandle responsestringhandle;
//Allocate memory for a LabVIEW string handle using LabVIEW's
//memory manager functions.
responsestringhandle=(LStrHandle)DSNewHandle(sizeof(int32)+256*sizeof(uChar));
PopulateStringHandle(responsestringhandle,"Du Lulu");
PostLVUserEvent(*responseref, (void *)&responsestringhandle);
return TRUE;
}
*/

extern "C" __declspec(dllexport) int functioncaller(UCHAR antChannel)
{
if(ANT_AssignResponseFunction != NULL && ANT_AssignChannelEventFunction != NULL)
{
ANT_AssignResponseFunction(&sendresponse, aucResponseBuffer);
ANT_AssignChannelEventFunction(antChannel, &sendevent, aucChannelEventBuffer);
return 1;
}

return 0;
}

void PopulateStringHandle(LStrHandle lvStringHandle,char* stringData)
{
//Empties the buffer
memset(LStrBuf(*lvStringHandle),'',256);

//Fills the string buffer with stringData
sprintf((char*)LStrBuf(*lvStringHandle),"%s",stringData);

//Informs the LabVIEW string handle about the size of the size
LStrLen(*lvStringHandle)=strlen(stringData);

return;
}
</div>
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
16.11.2008, 10:51
Beitrag #4

rolfk Offline
LVF-Guru
*****


Beiträge: 2.302
Registriert seit: Jun 2007

alle seit 6.0
1992
EN

2901GG
Niederlande
ANTDKT3
' schrieb:hallo rolf, hallo LabVIEWforum,

wenn ich das richtig verstanden habe sollte das so laufen:

1.ich mache einen create user event --> übergebe die refnum meiner event funktion.
2. in meiner dll lege ich globale vars an z.b. für meinen char buffer.
3. in meiner event funktion kann ich dann mit postlvuserevent die daten an LabVIEW schicken.
4. die event funktion ist sogleich meine callback funktion - also übergebe ich die adresse an den aufrufer.

so habe ich das verstanden. nun - es funktioniert nicht, also muss ich das falsch verstanden haben. wichtig: laut herstellerbeschreibung sollte jedes mal, wenn die hw angesprochen wird automatisch die callbackfunktion und der buffer (von ant_assign*) genutzt werden.

tut mir leid, dass ich so lästig bin, aber ich kämpfe nun schon sehr lange mit diesem zeug herum und bin echt schon am verzweifeln. außerdem ist ant ja eine gute sache, und wenn das in LabVIEW funken würde wärs ja auch was...

Also Du hast da einen typischen Knopf in Callback und so. Z.B. sehe ich dass Du eine ANT_AssignResponseFunction hast und ihr als Funktionsparameter eine Function sendresponse() übergibst die eine LabVIEW Refnum als Paramater hat. Das kann ja wohl so nicht functionieren, woher soll denn Deine ANT DLL bitte schön wissen wo sie diese Refnum hernemen soll?

Ich sehe da auch noch eine ANT_ResponseFunction() die wohl besser geeignet wäre um als Parameter für ANT_AssignResponseFunction () zu dienen.

Ausserdem kann ich Deine Aussage dass ANT eine gute Sache ist nicht nachvollziehen, da ich noch nie davon gehört habe Wink

Rolf Kalbermatter

Rolf Kalbermatter
Technische Universität Delft, Dienst Elektronik und Mechanik
https://blog.kalbermatter.nl
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
16.11.2008, 14:28
Beitrag #5

masht Offline
LVF-Grünschnabel
*


Beiträge: 11
Registriert seit: Sep 2008

8.5
2007
de

1150
Oesterreich
ANTDKT3
' schrieb:Also Du hast da einen typischen Knopf in Callback und so. Z.B. sehe ich dass Du eine ANT_AssignResponseFunction hast und ihr als Funktionsparameter eine Function sendresponse() übergibst die eine LabVIEW Refnum als Paramater hat. Das kann ja wohl so nicht functionieren, woher soll denn Deine ANT DLL bitte schön wissen wo sie diese Refnum hernemen soll?

Ich sehe da auch noch eine ANT_ResponseFunction() die wohl besser geeignet wäre um als Parameter für ANT_AssignResponseFunction () zu dienen.

Ausserdem kann ich Deine Aussage dass ANT eine gute Sache ist nicht nachvollziehen, da ich noch nie davon gehört habe Wink

Rolf Kalbermatter

hallo rolf,

danke für die antwortSmile

ok. ist das richtig, dass ich dann die funktion sendresponse() dazu nutze um die refnum an meine dll zu übergeben. diese schreib ich dann in eine globale var meiner dll.

ich nehme dann ANT_ResponseFunctio() und rufe von dort aus PostLVUserEvent mit der refnum, die in der global steht auf?

danke nochmal vielmals für die hilfe! Lol

ps.: zum thema ant - ich will keine werbung machen, aber es ist eine super einfache methode (wenn ma nicht gerade versuche da ding in LabVIEW einzubindenWink) um sensoren drathlos zu machen. viele sportgeräte benutzen das zb. suunto, garmin...
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
17.11.2008, 07:46
Beitrag #6

rolfk Offline
LVF-Guru
*****


Beiträge: 2.302
Registriert seit: Jun 2007

alle seit 6.0
1992
EN

2901GG
Niederlande
ANTDKT3
' schrieb:hallo rolf,

danke für die antwortSmile

ok. ist das richtig, dass ich dann die funktion sendresponse() dazu nutze um die refnum an meine dll zu übergeben. diese schreib ich dann in eine globale var meiner dll.

ich nehme dann ANT_ResponseFunctio() und rufe von dort aus PostLVUserEvent mit der refnum, die in der global steht auf?

Klingt ziemlich korrek. Ich würde in sendresponse() auch die Callbackfunktion selber installieren und falls möglich einen weiteren Boolean Parameter vorsehen um diese auch wieder zu deinstallieren.

Rolf Kalbermatter

Rolf Kalbermatter
Technische Universität Delft, Dienst Elektronik und Mechanik
https://blog.kalbermatter.nl
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
17.11.2008, 22:01
Beitrag #7

masht Offline
LVF-Grünschnabel
*


Beiträge: 11
Registriert seit: Sep 2008

8.5
2007
de

1150
Oesterreich
ANTDKT3
' schrieb:Klingt ziemlich korrek. Ich würde in sendresponse() auch die Callbackfunktion selber installieren und falls möglich einen weiteren Boolean Parameter vorsehen um diese auch wieder zu deinstallieren.

Rolf Kalbermatter

Hallo Rolf,

du glaubst ja gar nicht, wie sehr du mir geholfen hast :Dunglaublich - es funktioniert fast. d.h. ich mach das jetzt genau so wie besprochen.

ein problem habe ich aber noch - der event wird in der richtigen frequenz ausgelöst und daten werden übertragen, aber anscheinend wird der Buffer nicht korrekt aktualisiert, d.h. die der string ändert sich nicht. zuerst hatte ich die befürchtung, dass das memcpy bei abgebrochen wird (da die daten ca. so aussehen 01 41 00 00 09 01..). aber die funktion kopiert ja wirklich alles zum LVbuffer.

die buffer die ich verwende sind ja auch globale variablen in meine dll, deshalb habe ich mir gedacht, dass das schon so passt, oder muss ich von LabVIEW aus einen cstring zeiger mit der gewünschten adresse an meine dll übergeben und dort die daten hineinschreiben?

Danke für die Hilfe Lol

<div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>// antwrapper.cpp : Definiert die exportierten Funktionen für die DLL-Anwendung.
//

#include "stdafx.h"
#include "stdio.h"
#include "extcode.h" //LabVIEW inlcude

//Definitionen der Laenge für die Buffer
#define EVENT_LAENGE 10
#define RESPONSE_LAENGE 5

//Typendifinitionen für die ANT Funktionen
typedef BOOL (*ptreventfunction)(UCHAR ucChannel, UCHAR ucEvent);
typedef BOOL (*ptrresponsefunction)(UCHAR ucChannel, UCHAR ucMsgId);

typedef void (*ANT_RESPONSE_POINTER)(ptrresponsefunction, UCHAR*);
typedef void (*ANT_EVENT_POINTER)(UCHAR, ptreventfunction, UCHAR*);

//ANT Buffer & Globals
UCHAR aucResponseBuffer[5]={};
UCHAR aucChannelEventBuffer[10]={};

LVUserEventRef *eventref;
LVUserEventRef *responseref;
LStrHandle eventStringHandle;
LStrHandle responseStringHandle;

BOOL ANT_ChannelEventFunction(UCHAR ucChannel, UCHAR ucEvent);
BOOL ANT_ResponseFunction(UCHAR ucChannel, UCHAR ucMsgId);

extern "C" __declspec(dllexport) int ANT_LabVIEW_Schnittstelle(LVUserEventRef *eventrefLabVIEW, LVUserEventRef *responserefLabVIEW, UCHAR antChannel)
{
int ok = 0;

//Übergaben von den LabVIEWRefs an Globale Variable
eventref=eventrefLabVIEW;
responseref=responserefLabVIEW;

//Eventstringhandle Speicher zuweisen
// Allocate LabVIEW User Event Data
responseStringHandle=(LStrHandle)DSNewHandle(sizeof(int32)+RESPONSE_LAENGE*sizeo​
(UCHAR));
LStrLen(*responseStringHandle)=RESPONSE_LAENGE;
eventStringHandle=(LStrHandle)DSNewHandle(sizeof(int32)+EVENT_LAENGE*sizeof(UCHA​
));
LStrLen(*eventStringHandle)=EVENT_LAENGE;


//Zeiger auf die ANT_Funktionen definieren
ANT_RESPONSE_POINTER ANT_AssignResponseFunction;
ANT_EVENT_POINTER ANT_AssignChannelEventFunction;

//ANT_DLL laden
HINSTANCE hANTdll = LoadLibraryA("ANT_DLL.dll");
if (hANTdll != NULL){

//Pointer auf die Funktionen setzen
ANT_AssignResponseFunction = (ANT_RESPONSE_POINTER) GetProcAddress(hANTdll, "_ANT_AssignResponseFunction");
ANT_AssignChannelEventFunction = (ANT_EVENT_POINTER) GetProcAddress(hANTdll, "_ANT_AssignChannelEventFunction");
}
//Funktionen aufrufen
if(ANT_AssignResponseFunction != NULL && ANT_AssignChannelEventFunction != NULL)
{
ANT_AssignResponseFunction((ptrresponsefunction)ANT_ResponseFunction, aucResponseBuffer);
ANT_AssignChannelEventFunction(antChannel, (ptreventfunction)ANT_ChannelEventFunction, aucChannelEventBuffer);
ok=1;
}

else
ok=0;


//ANT_DLL freigeben
FreeLibrary(hANTdll);

return ok;
}

//ChannelEventFunction
BOOL ANT_ChannelEventFunction(UCHAR ucChannel, UCHAR ucEvent)
{
//ANT Event Daten --> LabVIEWstring

memcpy((char*)LStrBuf(*eventStringHandle), &ucChannel, 1);
memcpy((char*)LStrBuf(*eventStringHandle)+1, &ucEvent, 1);
memcpy((char*)LStrBuf(*eventStringHandle)+2, &aucChannelEventBuffer,strlen(aucChannelEventBuffer)+1);

//Stringhandle an LabVIEW
PostLVUserEvent(*eventref, (void*)&eventStringHandle);

return TRUE;
}

//ResponseFunction
BOOL ANT_ResponseFunction(UCHAR ucChannel, UCHAR ucMsgId)
{
//ANT Response Daten --> LabVIEWstring

memcpy((char*)LStrBuf(*responseStringHandle), &ucChannel, 1);
memcpy((char*)LStrBuf(*responseStringHandle)+1, &ucMsgId, 1);
memcpy((char*)LStrBuf(*responseStringHandle)+2, &aucResponseBuffer, strlen(aucResponseBuffer)+1);

//Post event to Event structure
PostLVUserEvent(*responseref,(void*)&responseStringHandle);

return TRUE;
}</div>
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
18.11.2008, 08:36 (Dieser Beitrag wurde zuletzt bearbeitet: 18.11.2008 08:39 von rolfk.)
Beitrag #8

rolfk Offline
LVF-Guru
*****


Beiträge: 2.302
Registriert seit: Jun 2007

alle seit 6.0
1992
EN

2901GG
Niederlande
ANTDKT3
' schrieb:Hallo Rolf,

du glaubst ja gar nicht, wie sehr du mir geholfen hast :Dunglaublich - es funktioniert fast. d.h. ich mach das jetzt genau so wie besprochen.

ein problem habe ich aber noch - der event wird in der richtigen frequenz ausgelöst und daten werden übertragen, aber anscheinend wird der Buffer nicht korrekt aktualisiert, d.h. die der string ändert sich nicht. zuerst hatte ich die befürchtung, dass das memcpy bei abgebrochen wird (da die daten ca. so aussehen 01 41 00 00 09 01..). aber die funktion kopiert ja wirklich alles zum LVbuffer.

die buffer die ich verwende sind ja auch globale variablen in meine dll, deshalb habe ich mir gedacht, dass das schon so passt, oder muss ich von LabVIEW aus einen cstring zeiger mit der gewünschten adresse an meine dll übergeben und dort die daten hineinschreiben?

Danke für die Hilfe Lol

Also ich habe bis jetzt noch nicht String oder Array Handles als Datenelemente in UserEvents von meinem C Code gebraucht. Grundsätzlich sind da aber zwei Möglichkeiten:

Entweder erwartet die LVPostUserEvent() Funktion dass sie Handles erben kann oder nicht.

Ich tendiere dazu anzumehmen dass sie das eben schon will, da dass mit dem allgemeinen Speicherkonzept von LabVIEW einhergeht.

Das heisst LVPostUserEvent nimmt ganz einfach an, dass ein Handle in den userEvent Daten nicht kopiert werden muss sondern einfach geerbt werden kann. Das ist auch speicherplatzmässig und in runtime performance effizienter.

Das heisst für Dich Du musst vor jedem PostUserEvent einen LStrHandle anlegen, die gewünschten Daten hineinekopieren und als Parameter an die Funktion mitgeben. Wenn Du beim Konzept der StringHandles bleiben willst wäre eventuel die Funktion LStrPrintf() für Dich interessant. Du musst ihr zwar ein gültiges LStrHandle übergeben (DSNewHClr(4) ist dafür aber genug) aber das formatieren des Strings und anschliessendes korrektes Resizen des Handle's sowie einfüllen der richtigen Anzahl Characterelemente macht alles die LStrPrintf() Funktion für Dich.

Sobald die LVPostUserEvent() Funktion zurückkehrt musst Du dieses Handle als von LabVIEW konsumiert betrachten und ist es in Deiner Funktion halt nicht mehr benützbar. Keine globalen LStrHandle also!

Wenn ich falsch habe, solltest Du den Speicher langsam umhoch gehen sehen da bei jedem Aufruf ein Speicherhandle verloren geht aber ich glaube es eher nicht.

Rolf Kalbermatter

Rolf Kalbermatter
Technische Universität Delft, Dienst Elektronik und Mechanik
https://blog.kalbermatter.nl
Webseite des Benutzers besuchen Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
20.11.2008, 20:42
Beitrag #9

masht Offline
LVF-Grünschnabel
*


Beiträge: 11
Registriert seit: Sep 2008

8.5
2007
de

1150
Oesterreich
ANTDKT3
' schrieb:Also ich habe bis jetzt noch nicht String oder Array Handles als Datenelemente in UserEvents von meinem C Code gebraucht. Grundsätzlich sind da aber zwei Möglichkeiten:

Entweder erwartet die LVPostUserEvent() Funktion dass sie Handles erben kann oder nicht.

Ich tendiere dazu anzumehmen dass sie das eben schon will, da dass mit dem allgemeinen Speicherkonzept von LabVIEW einhergeht.

Das heisst LVPostUserEvent nimmt ganz einfach an, dass ein Handle in den userEvent Daten nicht kopiert werden muss sondern einfach geerbt werden kann. Das ist auch speicherplatzmässig und in runtime performance effizienter.

Das heisst für Dich Du musst vor jedem PostUserEvent einen LStrHandle anlegen, die gewünschten Daten hineinekopieren und als Parameter an die Funktion mitgeben. Wenn Du beim Konzept der StringHandles bleiben willst wäre eventuel die Funktion LStrPrintf() für Dich interessant. Du musst ihr zwar ein gültiges LStrHandle übergeben (DSNewHClr(4) ist dafür aber genug) aber das formatieren des Strings und anschliessendes korrektes Resizen des Handle's sowie einfüllen der richtigen Anzahl Characterelemente macht alles die LStrPrintf() Funktion für Dich.

Sobald die LVPostUserEvent() Funktion zurückkehrt musst Du dieses Handle als von LabVIEW konsumiert betrachten und ist es in Deiner Funktion halt nicht mehr benützbar. Keine globalen LStrHandle also!

Wenn ich falsch habe, solltest Du den Speicher langsam umhoch gehen sehen da bei jedem Aufruf ein Speicherhandle verloren geht aber ich glaube es eher nicht.

Rolf Kalbermatter

Hallo Rolf, liebe LabVIEWforumnutzer,

@rolf: danke vielmals für deine hilfe. es hat alles funktioniert - auch das mit dem string (ich bin einfach zu schlampig, und hab die buffer zu klein dimensioniert..)

jedenfalls funktioniert jetzt ant unter LabVIEW. ich muss noch ein paar sachen ausprogrammieren (zb. für acknowledge messages usw.) wenn dass dann fertig ist, und wer interesse hat das zu nutzen kontaktiert mich einfach - da mir so viel geholfen wurde, möchte ich auch anderen helfen, deshlab gibts den code, die dll und vis natürlich gratis von mir für jede(n) der das brauchen kann.

liebe grüße aus wien
masht
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
Antwort schreiben 


Gehe zu: