Hallo alle zusammen,
folgende Problematik ist:
Einen bestehenden Code (C++ und QT "4.8").
Aus dieses Code kann man einen DLL File erstellen. Was auch machbar ist.
Nun wollte ich dieses DLL in Labview (als Library importieren)
integrieren.
Das kann ich auch teilweise lösen in dem ich einen C_Wrapper schreiben
und in Labview importieren (so viel zu Theorie).
Meine Frage an euch ist:
Wie machbar ist meinen Vorhaben?
Da QT teilweise Complexe Datentyp beinhaltet wie QString, QList und
.....,
kann ich nicht schätzen wie umständlich ist meine Vorhaben?
Daniel schrieb:> kann ich nicht schätzen wie umständlich ist meine Vorhaben?
kann ich auch nicht.
Kommt drauf an, wie viele Funktionsaufrufe du umsetzen musst und wie fit
du bist.
Klaus W. schrieb:> Kommt drauf an, wie viele Funktionsaufrufe du umsetzen musst und wie fit> du bist.
ja das stimmt.
In Labview habe ich nur Grundwissen und meinen Arbeitsgeber ist auch
bereit eine Weiterbildung zu bezahlen falls nötig aber meine Frage ist:
Ist das überhaupt machbar trotz der komplexen QT Datentypen.
Daniel schrieb:> Ist das überhaupt machbar trotz der komplexen QT Datentypen.
Dein Labview wird damit nichts anfangen können, deshalb musst du doch
eine Zwischenschicht bauen. Aber nur du kannst wissen, was alles darüber
gehen soll.
Daniel schrieb:> Ist das überhaupt machbar trotz der komplexen QT Datentypen.
Die darfst Du in Deinem C-Interface nicht exportieren, sondern musst in
C verwendbare Datentypen nutzen und entsprechend hin- und
herkonvertieren.
Darum muss sich Dein Wrapper kümmern; da Du ja nicht die Funktionalität
von QT selbst anbieten willst, sondern nur die eines mit QT
geschriebenen Programmes, sollte das realisierbar sein.
Mach Dir also zuerst mal Gedanken darüber, welche Funktionen denn Deine
DLL zur Verfügung stellen muss, und dann, falls dabei Funktionen sind,
die QT-spezifische Datentypen nutzen, wie diese sich auf C
transformieren lassen.
Folgende vorhaben
IstStand:
Board (Pic 8 Bit)
Application (GUI), die in (C++, QT) geschrieben ist.
Board wird mit dieses Application gesteuert.
Um das Board bzw. die Kommunikation mit dem PIC zu gewährleisten ist
einen HID.dll nötig.
Unterschiedliche Messungen werden durchgeführt und deren Ergebnis in GUI
dargestellt, was einwandfrei lauft.
Ziel:
Einen schnittstelle für Labview zu bauen.
Wie ich vorgegangen bin:
C_Wrapper geschrieben, der die wichtigste Funktionen beinhaltet.
Dieses C_Wrapper in Labview importiert (alle Funktionen der C_Wrapper
könnten ohne Problem importiert werden).
Labview gestartet um zu testen.(Es funktioniert leider nichts. Ich
bekomme sogar keine Fehlermeldung).
Meine Idee:
Vielleicht ist die Kommunikation mit dem Board gar nicht da.
Es muss vielleicht für die "HID.dll" auf Labview Seite was angepasst
werden?
Rufus Τ. F. schrieb:> Schreib ein Testprogramm, das anstelle von LabView mit Deiner DLL> kommuniziert. Dann kannst Du genauer untersuchen, was geschieht.
Und natürlich unter Benutzung des Wrappers und in reinem C, um dessen
Funktion zu testen.
--> Um dieses DLL zu testen habe ich TestProgramm geschrieben und es
funktinoiert einwandfrei.
Ich habe auch das DLL in Labview importiert und es funktioniert.
Nun habe ich eine Frage m bezug auf meinem TestProgramm, der so
aussieht:
1
#include "stdafx.h"
2
//#include <tchar.h>
3
#include "C_DllWrapper.h"
4
#include <iostream>
5
using namespace std;
6
7
int _tmain(int argc, _TCHAR* argv[])
8
{
9
Wrapper wrapper = {}; // Wie soll ich meinen struct initialisieren ?
10
11
12
double a1 = 12, a2 = 17;
13
createWrapper(a1,a2);
14
//double ergebnis;
15
//createWrapper(12,13);
16
cout << Add(wrapper,a1,a2) <<"--------" << endl;;
17
cout << Subst(wrapper,a1,a2)<< "+++++++" << endl;
18
cout << Mult(wrapper,a1,a2)<< "########" << endl;
19
//Add(wrapper,12,13);
20
getchar();
21
return 0;
22
}
Wie soll ich meinen struct initialisieren?
Hier in der Dummy Projekt könnte mit 0 initialisiert werden, aber was
wäre der richtige vorgehen?
Daniel schrieb:> In meinem richtigen Projekt bekomme ich einen Unhandled exception?
Dann mach im Wrapper doch um alles C++, das du aufrufst, ein try rum und
fange die Ausnahmen.
Hört sich so an, als hättest Du in dem Wrapper für die richtige Library
irgendwo in der Ansteuerung einen Fehler drin (oder die ist kaputt und
schmeisst immer ne exception und wird in dem C++ basierten Hauptprogramm
sonst immer abgefangen).
Hi,
steht dir eigentlich der Quellcode von der HID.dll zur Verfügung?
Probiere lieber diese direkt mit deinem wrapper anzusprechen.
Alternativ guck in den QT,c++ code nach dem header für die hid.DLL und
was das c++ Programm an Parametern an die einzelnen Funktionen übergibt.
Dein funktionierendes Beispiel schreibst du dann einfach Funktion für
Funktion um. Datentypen bei einer einfachen Ansteuerung musst du
bestimmt nicht umkopieren, hier gehts ja nur um eine einfache
Ansteuerung, wahrscheinlich werden maximal ein paar arrays kopiert
werden müssen.
Ich kann mir gut vorstellen, dass in der hid.DLL nur die Ansteuerung für
den Port implementiert ist. Such in deinem qt c++ nach Funktionen welche
dein Gerät initialisieren, Daten sendet (bestimmt ein eigenes Protokoll
mit CRC), die Daten empfangen und CRC prüft, Verbindung mit Gerät
trennt.
fry schrieb:> steht dir eigentlich der Quellcode von der HID.dll zur Verfügung?
@Leider nein
fry schrieb:> Such in deinem qt c++ nach Funktionen welche> dein Gerät initialisieren, Daten sendet (bestimmt ein eigenes Protokoll> mit CRC), die Daten empfangen und CRC prüft, Verbindung mit Gerät> trennt.
Genau das habe ich als erst versucht aber leider ich bekomme stets einen
Unhandled exception.
Ich habe in meinem C++ Quellencode einen Try {}Ausnahme angehängt um die
Exception abzufangen aber es scheint das Problem noch tiefer.
Ich muss der Code (C++) noch weiteruntersuchen.
Hat jemenden so einen Projekt(C++, Qt) gehabt und für ihm einen Wrapper
geschrieben?
Danke für den Feadback
Such in dem QT Programm mal nach dem header für die hid.dll
Probier diese in einem neuen Programm anzusprechen.
Die Anleitung hier ist ziemlich gut:
https://msdn.microsoft.com/en-us/library/ms810279.aspx
Dann schreib, ob du beim aufrufen der Funktionen noch immer Exceptions
bekommst.
Hallo Zusammen,
Das HID class.dll wird schon geladen und ich kann die Methoden der HID
class.dll aufrufen so weit so gut.
Nun habe ich festgestellt, dass meinen Struct (in echten Projekt) gleich
0 ist, was nicht richtig ist.
Ich glaube in meine Funktion createWrapper ist was faul.
So sieht es meine Ursprüngliche Objekt aus:
Original Class:
1
class MyClass : public QObject
2
{
3
Q_OBJECT
4
5
public:
6
MYCLASS_EXPORT MyClass(bool boSimulate_p, QString &strFileSettings_p=QString("settingsFile.ini")); // settingsFile ist eine ini File und bestimmte Einstellung zu speichern und wieder aufzurufen
Daniel schrieb:> Ich glaube in meine Funktion createWrapper ist was faul.
Wenn du das beim Testen auch so gemacht hast
1
int_tmain(intargc,_TCHAR*argv[])
2
{
3
Wrapperwrapper={};// Wie soll ich meinen struct initialisieren ?
4
5
6
doublea1=12,a2=17;
7
createWrapper(a1,a2);
dann sicherlich.
Du kriegst von createWrapper ein Wrapper-Objekt zurück. Damit musst du
natürlich auch was machen. Zb dem wrapper Objekt zuweisen
1
....
2
wrapper=createWrapper(a1,a2);
und erst dann kannst du dieses Proxy Objekt wieder in die Funktionen zur
Benutzung der DLL reinstecken.
Ansonsten: wenn sonst nichts hilft:
In der Zwischenschicht ein File aufmachen und alle aufgerufenen
Funktionen schreiben eine Meldung samt Auflistung der Funktionsparameter
rein. Dann kann man zumindest nachvollziehen, welche Aufrufe in welcher
Reihenfolge getätigt werden, welche Argumente vom Aufrufer übergeben
wurden und den Returnwert aus den Tiefen des CPP Teiles kann man auch
noch ins File schreiben.
Und dann sieht man weiter, wenn man da mit dem Debugger nicht ran kann.
Wieviele derartige Wrapper Objekte brauchst du denn?
Da du erwähnt hast, dass es sich dabei um eine Kommunikation mit einem
PIC handelt, wird es wohl nur ein einziges derartiges Objekt geben.
In diesem Fall brauchst du das auch nicht über die DLL-Grenzen zu
exportieren, sondern die C++-Zwischenschicht hält sich dieses als
Variable bei sich. Dann muss man auch nicht dauernd rumcasten.
Frei nach dem Muster
1
// DLL_Test_Labview.cpp : Defines the exported functions for the DLL application.
2
//
3
4
#include"stdafx.h"
5
#include"MyClass.h"
6
#include"C_DllWrapper.h"
7
8
staticMyClass*pImpl=NULL;
9
10
DLLIMPORTvoidcreateWrapper(doublea,doubleb)
11
{
12
deletepImpl;
13
pImpl=newMyClass(a,b);
14
}
15
16
DLLIMPORTvoiddestoryWrapper(void)
17
{
18
deletepImpl;
19
pImpl=NULL;
20
}
21
22
DLLIMPORTdoubleAdd(doublea,doubleb)
23
{
24
if(pImpl)
25
returnpImpl->Add(a,b);
26
27
return0.0;
28
}
29
....
Für die Return Werte könntest du dir noch was einfallen lassen, zb ein
paar Fehlercodes, wenn versucht wird mit einem NULL Pointer zu
operieren.
Hi alle zusammen,
Ich bin mittlerweile weiter gekommen.
Nun hakt in eine Sache und zwar:
eine Methode von meinem C_Wrapper hat als Rückgabeparameter eine Klasse
Bclass .
nehmen wir einen Beispiel:
Die Methode sieht so aus:
1
Bclass Measure(MYCLASSWrapper LV_ref_MyClass);
Bclass ist wie folgende definiert :
1
class Bclass
2
{
3
public:
4
Bclass();
5
Bclass(Sclass * pSclass);
6
Bclass(const Bclass *e) ; // CopyConstructor
7
{
8
s1 = e.s1;
9
s2 =e.s2;
10
.....
11
}
12
virtual ~Bclass(){}
13
.....
14
15
};
Sclass ist wie folgende definiert:
1
class Sclass: public Aclass, public Eclass, public Dclass
2
{
3
....
4
5
};
Meine Frage ist :wie soll ich meine Wrapper für dieses Funktion "Bclass
Measure(MYCLASSWrapper LV_ref_MyClass)" schreiben?
Daniel schrieb:> eine Methode von meinem C_Wrapper hat als Rückgabeparameter eine Klasse> Bclass .
Das ist nur dann sinnvoll, wenn dieser Rückgabe"parameter" außerhalb
Deines Wrappers (d.h. in Labview) benötigt wird.
Ist das der Fall? Wozu ist dieser Rückgabe"parameter" da?
Rufus Τ. F. schrieb:> Das ist nur dann sinnvoll, wenn dieser Rückgabe"parameter" außerhalb> Deines Wrappers (d.h. in Labview) benötigt wird.>> Ist das der Fall?
Ja
>Wozu ist dieser Rückgabe"parameter" da?
Diese Rückgabe ist da um das Objeckt der von einen andere Klasse erzeugt
wird weiterzuberechnen.
Daniel schrieb:> Diese Rückgabe ist da um das Objekt der von einen andere Klasse erzeugt> wird weiterzuberechnen.
Dann musst die doch nicht exponieren, oder? Mach die Berechnung
innerhalb des Wrappers und gib nur das Ergebnis zurück, z.B. als struct.
Allgemein ist es schwierig zu beurteilen was genau in Deinem Fall Sinn
ergibt, da wir uns nur über Platzhalter unterhalten und wir nicht genau
wissen was da passiert. Du solltest vielleicht versuchen es so einfach
wie möglich zu halten, d.h. überleg Dir welches Minimum an Informationen
Du in deinen Wrapper stecken mußt und was an Informationen Du dann in
dem Labview Teil dann wirklich verarbeiten mußt. Entsprechend bastelst
Du Dir C Funktionen zusammen die Datentypen die C kennt entgegennehmen
und wieder zurück geben. Wenn Du irgendwelche Objekte an andere
übergeben mußt, machst Du das innerhalb des Wrappers, z.B. innerhalb
einer Funktion
struct_type measure_and_calculate() oder indem Du das Objekt innerhalb
des Wrappers zwischenspeicherst und nacheinander eine measure und
calculate Funktion aufrufst.
Daniel schrieb:> Diese Rückgabe ist da um das Objeckt der von einen andere Klasse erzeugt> wird weiterzuberechnen.
Das bedeutet, das Ding wird weiteren Funktionen Deiner DLL übergeben,
die von LabView aufgerufen werden?
Wenn das so ist: Mach da 'nen opaken Pointer draus. LabView selbst kann
mit dem Ding nichts anfangen.
Rufus Τ. F. schrieb:> Das bedeutet, das Ding wird weiteren Funktionen Deiner DLL übergeben,> die von LabView aufgerufen werden?
Jaein
Die RückgabeParameter brauche ich die nur zu darstellen.
Das ganze ist natürlich ein Herumgerate, da es an konkreten
Informationen fehlt, Bezeichnungen wie Objekt und Klasse wild
durcheinander geworfen werfen und das ganze ist mit sprachlichen Mängeln
gewürzt, aber:
Was weiter verarbeitet wird ist ein Objekt vom Typ Sclass, wobei dieses
Objekt durch die Methode Bclass Measure(MYCLASSWrapper LV_ref_MyClass)
über den Konstruktor an ein Objekt vom Typ Bclass übergeben wird. Bclass
hat vermutlich irgendwelche Getter die von Daniel nicht gezeigt wurden,
um Einzelwerte, Arrays oder sonstwas für ("brauche ich die nur zu
darstellen.") die Darstellung in Labview zu extrahieren. Wenn ich das so
richtig verstanden habe, dann müssen innerhalb des Wrappers, in der
Funktion ...Measure... die entsprechenden Getter aufgerufen und die
Resultate in C Datentypen kopiert werden, die dann z.B. als struct als
Rückgabewert benutzt werden (oder über einen zusätzlichen Parameter).
physiker schrieb:> Was weiter verarbeitet wird ist ein Objekt vom Typ Sclass, wobei dieses> Objekt durch die Methode Bclass Measure(MYCLASSWrapper LV_ref_MyClass)> über den Konstruktor an ein Objekt vom Typ Bclass übergeben wird. Bclass> hat vermutlich irgendwelche Getter die von Daniel nicht gezeigt wurden,> um Einzelwerte, Arrays oder sonstwas für ("brauche ich die nur zu> darstellen.") die Darstellung in Labview zu extrahieren. Wenn ich das so> richtig verstanden habe, dann müssen innerhalb des Wrappers, in der> Funktion ...Measure... die entsprechenden Getter aufgerufen und die> Resultate in C Datentypen kopiert werden, die dann z.B. als struct als> Rückgabewert benutzt werden (oder über einen zusätzlichen Parameter).
Du hast genau auf dem Punkt gebracht. I am Sorry für die Sprachlichen
Mängeln.
Es ist genau das was ich auch getan habe.
Daniel schrieb:> Keine Ahnig
ich auch nicht.
Ehrlich gesagt habe ich keinen Schimmer, worum es jetzt noch geht.
Und auch keine Lust, aus dem Gestammel etwas zu raten.
Hallo alle zusammen,
es hat sich erledigt.
Danke für die Unterstützung.
Jetzt muss ich noch alle Mögliche Exception abfangen, dann das DLL in
Labview integrieren.
Hallo zusammen,
ich habe es noch einen kurze Frage:
Um das Board (PIC18f4550) mit Labview anzusprechen bzw. das Datenverkehr
einwandfrei laufen, muss ich in Labview NI-VISA Driver Wizard was
einstellen?
Bitte seh links
http://www.ni.com/tutorial/4478/de/
Danke
Hallo zusammen,
ich habe eine Frage:
Ist das Möglich der DLL mit Hilfe des Debuggers (Visual Studio ebene)
auf Fehler zu untersuchen?
Wenn ja wie soll ich den Visual Studio einrichten?
Danke in voraus
Zu Visual Studio kann ich wenig sagen, aber mit gdb sollte es gehen.
Einfach "gdb programmWelcheLibVerwendet" und dann breakpoints auf die
libraryfunktionen setzen.
Daniel schrieb:> Ist das Möglich der DLL mit Hilfe des Debuggers (Visual Studio ebene)> auf Fehler zu untersuchen?
Natürlich. Dafür ist das da.
Eine Möglichkeit: Programm aufrufen, das Deine DLL verwendet - in Visual
Studio "Debug - Attach to Process" ausführen.
Daniel schrieb:> bzw. wo finde ich das in Visual Studio?
Oben im Fenster gibt es ein Menü. Da steht "Debug". Und einer der Punkte
in dem sich nach Klicken auf "Debug" öffnenden Menü heißt "Attach to
Process".
Hallo Zusammen,
Problematik:
In der C_wrapper habe ich folgende:
1
....
2
struct MyStruct
3
{
4
double wert1;
5
double wert2;
6
double wert3;
7
.....
8
9
10
11
12
}; // Dieses struct beinhaltet sehr viel Messwerte.
13
14
//Funktion
15
MYStruct DefaultMeasure(...);
16
...
--> Diese Funktion hat als Rückgabeparameter "MYStruct" und das in
Labview zu interfacen ist nicht so einfach.
Meine Frage: wie soll ich das ambesten vorgehen?
Soll ich das in eine extra HilfFunktion shreiben und dann was habe ich
davon.
Dieses Werte möchte ich in Labview (GUI) darstellen
Deine Struktur scheint durch ein Array ersetzbar zu sein, wenn da
tatsächlich nur double-Werte drinstehen.
Ansonsten wirst Du Dir ansehen müssen, auf welche Art und Weise LabView
mit komplexen Datentypen umgeht und Deinen Wrapper so anpassen, daß er
zwischen den beiden Sichtweisen (Deiner und der von Labview) hin- und
her-übersetzt.
Rufus Τ. F. schrieb:> Deine Struktur scheint durch ein Array ersetzbar zu sein, wenn da> tatsächlich nur double-Werte drinstehen.
Die struct beinhaltet unterschiedliche Datentypen
Rufus Τ. F. schrieb:> Ansonsten wirst Du Dir ansehen müssen, auf welche Art und Weise LabView> mit komplexen Datentypen umgeht und Deinen Wrapper so anpassen, daß er> zwischen den beiden Sichtweisen (Deiner und der von Labview) hin- und> her-übersetzt
Sorry muss noch mal fragen:
Gibt es keinen anderen Weg, der etwas einfacher ist?
Ich kenne und nutze LabView nicht.
Kann das mit Arrays umgehen? Gibt es einen Grund, warum Deine Struktur
unterschiedliche Datentypen enthält? Muss auf jedes dieser
Strukturelemente aus LabView heraus zugegriffen werden können?
Rufus Τ. F. schrieb:> Ich kenne und nutze LabView nicht.>> Kann das mit Arrays umgehen?
Ja
> Gibt es einen Grund, warum Deine Struktur unterschiedliche Datentypen >enthält?
Ja
>Muss auf jedes dieser Strukturelemente aus LabView heraus zugegriffen >werden
können?
Nein
Diese werte sind nur auf Labview darzustellen, damit es festgestellt
werden, ob was schief bei der Messung gelaufen ist oder nicht.
Dieses Daten werden immer aktualisiert sobald eine Messung durchgeführt
ist.
Daniel schrieb:>>Muss auf jedes dieser Strukturelemente aus LabView heraus zugegriffen >werden> können?> Nein> Diese werte sind nur auf Labview darzustellen, damit es festgestellt> werden, ob was schief bei der Messung gelaufen ist oder nicht.
Das ist doch ein "Zugriff", was denn sonst. Entweder Du schaust Dir an
wie man ein struct in LabView weiterverarbeitet (cluster... hat eine
schnelle Google Suche ergeben) oder Du teilst es in zig Arrays auf und
gibts die separat zurück.
Was erwartest Du? Daß sich jemand hinsetzt und Deine reichlich
zusammenhangslosen letzten Beiträge durchliest, nur um eine nicht
gestellte Frage zu beantworten?