30.03.2011, 19:44
(Dieser Beitrag wurde zuletzt bearbeitet: 30.03.2011 20:05 von Reyneke.)
Beitrag #1
|
Reyneke
LVF-Neueinsteiger
Beiträge: 4
Registriert seit: Nov 2010
9.2
2009
de
Deutschland
|
Gewisse Unsichehreiten beim richtigen Umgang mit Clustern in Ausblick auf externen Co
Moin, ich hätte da ein oder zwei oder mehrere Fragen bezüglich Einbindung von bereit vorhandenem Quellcode nach LabView. Ich danke allen, die sich Zeit nehmen diesen Bericht zu lesen im Vorraus.
Eines vorweg: Es soll eine Verknüpfung zwischen LabView und EtherCAT mittels des EtherCAT Masters von Kithara Software konstruiert werden. Bisher steht (und läuft) der Master. Er erkennt auch angeschlossene Slaves und generell macht das, was ich bisher habe einen guten Eindruck.
Jetzt treten jedoch die ersten Fragen auf. Zum einen gibt es den Datentyp KSEcatDataObjInfo, in dem sich eine Verknüpfung auf KSEcatDataVarInfo befindet, die jedoch so ausschaut:
Code:
KSEcatDataVarInfo* vars[1]
, was mich ein wenig verunsichert. Ist es ein Pointer auf das erste Ergebnis, ein Feld angefüllt mit Informationen oder gar ein Feld voller Pointer auf die einzelnen Ergebnisse? Mein Tipp, da man die einzelnen Dateninformationen über, z.B. eine for-Schlefie mit vars[i] ansprechen kann, ist letzteres, aber so ganz sicher bin ich mir nicht, ebensowenig wie ich mir unsicher bin, wie sich das am Einfachsten nach LabView übersetzen lässt.
Die andere Frage, wäre, wie man einen void ** - pointer übermittelt. Meines Verständnisses nach, ist das eine doppelt verkettete Adresstruktur, also ein Pointer auf einen Pointer. Leider schmiert mir der Rechner mit einem Bluescreen ab, wenn ich das versuche so umszusetzen, das ich der Call Library Function einen u32 Wert überliefere.
Habt ihr einen Tipp für mich, wie ich diese Beiden Schwierigkeiten lösen kann, bitte?
Mit freundlichen Grüßen
- Reyneke
Edit: Ich bitte um Entschuldigung, wenn ich gerade programmiertechnisch wie der Ochs vom Berg stehe und einige sich gerade an den Kopf fassen. Mitunter, dank meiner ADHS, sehe ich den Wald vor lauter Bäumen nicht.
|
|
|
04.04.2011, 09:13
(Dieser Beitrag wurde zuletzt bearbeitet: 04.04.2011 09:16 von rolfk.)
Beitrag #2
|
rolfk
LVF-Guru
Beiträge: 2.306
Registriert seit: Jun 2007
alle seit 6.0
1992
EN
2901GG
Niederlande
|
RE: Gewisse Unsichehreiten beim richtigen Umgang mit Clustern in Ausblick auf externen Co
Grundsätzlich ist C in dieser Hinsicht sehr flexible um nicht zu sagen undeutlich.
Dein Vorbild:
KSEcatDataVarInfo* vars[1];
ist ausserhalb jeglichen Kontextes undeutlich zu interpretieren und eigentlich auch nur durch Dokumentation oder entsprechende Codebeispiele (die testbar funktionieren) eindeutig festzulegen.
Es geht um eine Variablendeklaration und dabei wird ein Pointer angelegt auf ein Array, das eventuel, möglicherweise, vielleicht, je nach Lust und Laune, eines, zwei, mehr oder kein Element enthalten kann. In C ist ein Pointer einfach ein Pointer.
Das Ganze liesse sich auch so schreiben:
KSEcatDataVarInfo** vars;
und wäre qua C syntax equivalent und ohne Probleme aneinander zuweisbar. Die einzige wirkliche Einschränkung in C ist der Datentyp des Pointers selber (KSEcatDataVarInfo), der Level der Referencierung, und wenn der Pointer als const deklariert wird, was bedeutet dass dieser Pointer nach einer ersten Initialisierung nicht mehr verändert werden kann.
C++ hat da ein paar weitere Syntaxfeatures hinzugefügt und stellt sich ein klein wenig (aber kaum nennenswert) strikter auf.
Ein void Pointer is auch einfach ein Pointer auf irgendwas. Gleiches Problem wie oben, aber die Einschränkung des Datentyps des Pointers entfällt komplet. Ein void Pointer is kompatibel mit jedem anderen Pointer, ob mit oder ohne Datentyp.
In LabVIEW ist ein void Pointer als Funktionsparameter einfach ein pointersized Integer, als Element in einer Struktur hauptsächlich viel Mühe, Schweiss und Kopfzerbrechen. Für mich ist jeder Pointer innerhalb einer Struktur auch gleich der Punkt wo ich schon lange jeglichen LabVIEW Diagramvodoo aufgebe und direkt in C eine DLL schreibe die das Ganze in viel LabVIEW-freundlichere Parameter umsetzt.
|
|
|
12.04.2011, 18:13
Beitrag #3
|
Reyneke
LVF-Neueinsteiger
Beiträge: 4
Registriert seit: Nov 2010
9.2
2009
de
Deutschland
|
RE: Gewisse Unsichehreiten beim richtigen Umgang mit Clustern in Ausblick auf externen Co
Okay, danke fuer den Tipp. ich habe inzwischen eine Wrapper Funktion entworfen, aber bisher ... naja ... laeuft es nicht so richtig.
Die Funktion schaut wie folgt aus:
Code:
#ifndef ___ETHERCATLV_H
#define ___ETHERCATLV_H
/* Call Library source file */
#include <extcode.h>
#include <ethercat.h>
#include <string.h>
/* lv_prolog.h and lv_epilog.h set up the correct alignment for LabVIEW data. */
#include "lv_prolog.h"
/* Typedefs */
typedef struct {
int32_t vendorId;
int32_t productId;
int32_t revision;
int32_t serial;
LStrHandle group;
LStrHandle image;
LStrHandle order;
LStrHandle name;
int32_t objCount;
} TD1;
typedef struct {
int32_t objType;
LStrHandle name;
int32_t bitLength;
int32_t index;
int32_t syncIndex;
int32_t varCount;
} TD2;
typedef struct {
int32_t objType;
LStrHandle name;
int32_t dataType;
int32_t bitLength;
int32_t subIndex;
} TD3;
#include "lv_epilog.h"
extern "C" {
_declspec(dllexport) uint32_t KS_queryEcatSlaveInfoLV(uint32_t hSlave, int32_t indexObject,
int32_t indexVariable, TD1 *pSlaveInfo, TD2 *pDataObjInfo,
TD3 *pDataVarInfo, int32_t flags);
}
_declspec(dllexport) uint32_t KS_queryEcatSlaveInfoLV(uint32_t hSlave, int32_t indexObject,
int32_t indexVariable, TD1 *pSlaveInfo, TD2 *pDataObjInfo,
TD3 *pDataVarInfo, int32_t flags)
{
KSEcatDataVarInfo* dataVarInfo_;
KSEcatDataObjInfo* dataObjInfo_;
KSEcatSlaveInfo* slaveInfo_;
Error error = KS_OK;
uint size = 0;
error = KS_queryEcatSlaveInfo((KSHandle) hSlave, &slaveInfo_, flags);
if (error == KS_OK) {
pSlaveInfo->vendorId = slaveInfo_->vendorId;
pSlaveInfo->productId = slaveInfo_->productId;
pSlaveInfo->revision = slaveInfo_->revision;
pSlaveInfo->serial = slaveInfo_->serial;
size = strlen(slaveInfo_->group);
memcpy(LStrBuf(*pSlaveInfo->group), slaveInfo_->group, size);
LStrLen(*pSlaveInfo->group) = size;
size = strlen(slaveInfo_->image);
memcpy(LStrBuf(*pSlaveInfo->image), slaveInfo_->image, size);
LStrLen(*pSlaveInfo->image) = size;
size = strlen(slaveInfo_->order);
memcpy(LStrBuf(*pSlaveInfo->order), slaveInfo_->order, size);
LStrLen(*pSlaveInfo->order) = size;
size = strlen(slaveInfo_->name);
memcpy(LStrBuf(*pSlaveInfo->name), slaveInfo_->name, size);
LStrLen(*pSlaveInfo->name) = size;
pSlaveInfo->objCount = slaveInfo_->objCount;
size = strlen(slaveInfo_->objs[indexObject]->name);
memcpy(LStrBuf(*pDataObjInfo->name), slaveInfo_->objs[indexObject]->name, size);
LStrLen(*pDataObjInfo->name) = size;
pDataObjInfo->bitLength = slaveInfo_->objs[indexObject]->bitLength;
pDataObjInfo->index = slaveInfo_->objs[indexObject]->index;
pDataObjInfo->syncIndex = slaveInfo_->objs[indexObject]->syncIndex;
pDataObjInfo->varCount = slaveInfo_->objs[indexObject]->varCount;
pDataVarInfo->objType = slaveInfo_->objs[indexObject]->vars[indexVariable]->objType;
size = strlen(slaveInfo_->objs[indexObject]->vars[indexVariable]->name);
memcpy(LStrBuf(*pDataVarInfo->name), slaveInfo_->objs[indexObject]->vars[indexVariable]->name, size);
LStrLen(*pDataVarInfo->name) = size;
pDataVarInfo->dataType = slaveInfo_->objs[indexObject]->vars[indexVariable]->dataType;
pDataVarInfo->bitLength = slaveInfo_->objs[indexObject]->vars[indexVariable]->bitLength;
pDataVarInfo->subIndex = slaveInfo_->objs[indexObject]->vars[indexVariable]->subIndex;
}
return error;
}
#endif // ___ETHERCATLV_H
Doch leider schmiert mir mein VI, mit dem ich teste, bereits im Laufen ab, bzw. wenn er mir die Informationen auf dem VI darstellen soll. Es kommt keine Fehlermeldung, es beendet sich einfach. Ich vermute, dass einer der Ein- und Ausgabe Faktoren falsch deklariert ist, aber so richtig komme ich gerade nicht weiter.
|
|
|
12.04.2011, 21:40
Beitrag #4
|
Reyneke
LVF-Neueinsteiger
Beiträge: 4
Registriert seit: Nov 2010
9.2
2009
de
Deutschland
|
RE: Gewisse Unsichehreiten beim richtigen Umgang mit Clustern in Ausblick auf externen Co
Ookay, manchmal steckt der Teufel in der Gewohnheit. Ich hatte die Variablen an der Node initialisiert. Die Integervariablen mit 0 ... und die Strings? Tja, aus alter Gewohnheit mit "NULL", was dann auch voellig legitim interpretiert wurde. Das Resultat war obenstehendes Phaenomen.
Jetzt muss ich den Error 1097 finden, der scheinbar auftritt wenn die Funktion wieder zurueckgekerht ist. Nunja - immerhin sehe ich bereits, dass die Wrapperfunktion korrekt laeuft.
|
|
|
14.04.2011, 10:59
(Dieser Beitrag wurde zuletzt bearbeitet: 19.04.2011 19:26 von rolfk.)
Beitrag #5
|
|
|
| |