Hallo Zusammen,
Programmiersprache: c++
Ziel: einen CWrapper schreiben dann in Labview importieren.
Problemstellung:
Wie soll ich der cluster für jede Funktion initialisieren?
Ich habe es einen DLL Dummy Projekt Mittel Visual studio 2012 erstellt.
Bitte seh folgende Anweisung:
http://labviewwiki.org/DLL/shared_library
Es sieht wie folgende aus:
// das baseclass Header File // zu wrappende Class
1
#ifndef _BASE_CLASS_H_
2
#define _BASE_CLASS_H_
3
4
class base
5
{
6
public:
7
base(double x_in);
8
virtual ~base(void);
9
void set_x(double x_in);
10
void get_x(double* x_out);
11
void sqr_x(void);
12
13
private:
14
double x;
15
};
16
17
#endif /* _BASE_CLASS_H_ */
// base_class cpp
1
#include "base_class.h"
2
#include <windows.h>
3
4
base::base(double x_in)
5
{
6
x = x_in;
7
}
8
9
base::~base ()
10
{
11
/* clean up */
12
}
13
14
void base::set_x(double x_in)
15
{
16
x = x_in;
17
}
18
19
void base::get_x(double* x_out)
20
{
21
*x_out = x;
22
}
23
24
void base::sqr_x(void)
25
{
26
x*=x;
27
}
c_dll_wrapper.h
1
#ifndef _C_DLL_WRAPPER_H_
2
#define _C_DLL_WRAPPER_H_
3
4
/* building a DLL */
5
#define DLLIMPORT __declspec (dllexport)
6
7
#ifdef __cplusplus
8
extern "C" { /* using a C++ compiler */
9
#endif
10
11
typedef struct base base; /* make the class opaque to the wrapper */
Der Rückgabewert von createbase ist ein Zeiger. Dieser Zeiger MUSS als
Wert an die get und set Funktionen übergeben werden! Als 1. Parameter.
Hierzu muss der anstelle des Clusters wieder ein U32 Wert verwendet
werden. Dann sollte das funktionieren. Mischen von Datentypen U32 und
Cluster ist hier nicht die Lösung ;-)
Wieso soll der gültige "c" Zeder überhaupt von LV verwaltet werden? LV
kann damit nix, aber auch garnix anfangen.
Verwalte den Zeiger da wo er benötigt wird, in der wrapper DLL.
Dietmar schrieb:> Der Rückgabewert von createbase ist ein Zeiger. Dieser Zeiger MUSS als> Wert an die get und set Funktionen übergeben werden! Als 1. Parameter.
--> Wo soll ich das tun auf C++ Seite in dem ich zb. bei set:
1
DLLIMPORT void set_x(base* LV_ref, double x_in)
2
{
3
LV_ref = create_base(double x_in);
4
LV_ref->set_x(x_in);
5
}
// es ist unschön da muss ich mehr mals LV_ref erzeugen ob das GUT IST?
schreibe oder auf Labview Seite "Das weiss es nicht wie das geht: Soll
ich die Labview library verwenden wie MoveBlock?"
Okocha schrieb:> // es ist unschön da muss ich mehr mals LV_ref erzeugen ob das GUT IST?
Warum denn das? Du kannst z.B. in Deinem Wrapper eine globale Variable
vom base* haben, der von create_base(double x_in) ein Wert zugewiesen
wird und auf den alle anderen zugreifen. Das ganze kannst Du natürlich
noch ein bisschen absichern, um sicher zu gehen, daß create_base bereits
aufgerufen wurde und nur einmal aufgerufen wird. Wenn es nur eine
Instanz geben soll, kannst Du Dir create_base auch ganz sparen und Dein
Wrapper erledigt das automatisch.
physiker schrieb:> Warum denn das? Du kannst z.B. in Deinem Wrapper eine globale Variable> vom base* haben, der von create_base(double x_in) ein Wert zugewiesen> wird und auf den alle anderen zugreifen. Das ganze kannst Du natürlich> noch ein bisschen absichern, um sicher zu gehen, daß create_base bereits> aufgerufen wurde und nur einmal aufgerufen wird.
Sorry
Ich muss wieder fragen:
Soll ich diese Globale Variable in der Wrapper schon tun?
So in der Art:
1
base* static_Var = NULL;
2
[\code]
3
und dann innerhalb der create_base(double x_in) so:
Also,
in dem VI getbase hast du einen U32 als Wert der aus der Wrapper DLL
geliefert wird. Das ist ein Zeiger, den generierst du ja in der DLL in
dem du die Funktion "createbase aufrufst.
--> DLLIMPORT base* create_base(double x_in) in deinem VI heist das Ding
ja "function return"
Das kann man so machen.
Das VI set_x benötigt nun genau diesen Wert. Du hast in dem VI einen
Cluster als Übergabeparameter angegeben "LV_ref". Diesen Cluster musst
du nun durch einen U32 ersetzen. Das musst du in dem Konfiguration voin
dem DLL aufruf machen.
Dann wird die "function return" mit dem neuen U32 Datentypen im
create_x.. verbunden. Damit hat nun die Funktion in der Wrapper DLL
einen gültigen Zeiger auf die abgeleitete Klasse und kann auf die
Elemente der KLasse zugreifen. Nun sollte keine NULL mehr zurück kommen.
Der ganze Code in der Wrapper ist eh kritisch, da nicht auf gültige
Zeiger kontrolliert wird.
Du kannst froh sein wenn dir dein System nicht komplett abstürzt und du
nur eine Schutzverletzung gemeldet bekommst.
Wenn du die Änderungen gemacht hast, zeig doch bitte mal das
Blockdiagramm mit Sequenz create_base - get_x - destroy_base
Btw: soclhe Stielblüten machen das lesen von Sourcecode nicht einfacher
;-)
Rein oder raus, aber nicht reinraus
#define DLLIMPORT __declspec (dllexport)
Gruß Dietmar
Hallo Dietmar,
anbei meine Änderung.
Es lauft nicht wie gewünscht weiss es nicht was ich verbockt habe.
Ich bekomme immer eine Fehlermeldung seh bitte Anhang.
Sorrrrrrrrrrrrrrrrrrrrrrrrrrryyyyyyyyyyyy
Ich meinte eigentlich das Blockdiagram von den zusammenhängenden VI's.
VI's einzeln aufrufen geht nicht. Sollte dann so aussehen wie oben.
Leider kann ich deine DLL hier nicht öffnen, habe nicht das neueste
Visual Studio hier laufen. Du hast eine Debug Version angehängt. Die
benötigt die Redistributables von M.
Eine Frage noch: Was ist das Ziel deiner Übung?
Willst du eine DLL erstellen um C-Code in Labview zugänglich zu machen?
Hast du eine bestehende DLL und willst auf diese zugreifen?
Wenn ja, hast du den Header der DLL? Eine Wrapper ist eigentlich nur
dann nötig wenn deine DLL wild mit Zeigern hantiert, da hat LV ein
Problem mit. Ansonsten kannst du dir den Wrapper sparen und direkt auf
die exportierten Funktionen zugreifen. Kannst du ggf. den Header
hiereinstellen oder weitere Infos zugänglich machen?
Im Augenblick sieht es so aus als wenn du auf mehreren baustellen
gleichzeitig arbeitest.
Dietmar schrieb:> Eine Frage noch: Was ist das Ziel deiner Übung?>
Ziel meine Übung ist eine bestehende DLL in Labview zu importieren.
> Willst du eine DLL erstellen um C-Code in Labview zugänglich zu machen?
ja habe ich schon gemacht.
> Hast du eine bestehende DLL und willst auf diese zugreifen?
ja habe ich auch erstellt.
>> Wenn ja, hast du den Header der DLL?
ja
>Eine Wrapper ist eigentlich nur> dann nötig wenn deine DLL wild mit Zeigern hantiert, da hat LV ein> Problem mit. Ansonsten kannst du dir den Wrapper sparen und direkt auf> die exportierten Funktionen zugreifen. Kannst du ggf. den Header> hiereinstellen oder weitere Infos zugänglich machen?>
ja
> Im Augenblick sieht es so aus als wenn du auf mehreren baustellen> gleichzeitig arbeitest.
Ich danke es dir für die grosse Hilfe
Hallo Dietmar,
in meine erste C_Wrapper habe ich einen Fehler gemacht.
Ich habe nicht den "base * LV_ref" als Parameter weitergegeben.
Die C_Wrapper ist dann so in der Art geschrieben:
Heaeder Anteil:
1
DLLIMPORT base* create_base(double x_in);
2
DLLIMPORT void set_x(double x_in);
3
DLLIMPORT void get_x(double* x_out);
4
DLLIMPORT void destroy_base();
5
DLLIMPORT void sqr_x();
CPP Teil:
1
base* StaticObject = NULL;
2
3
DLLIMPORT base* create_base(double x_in)
4
{
5
return new base(x_in);
6
}
7
.......
und natürlich habe ich dann keine Terminals und ist auch nicht die
schlauste Idee
Hast du den Zugriff jetzt fehlerfrei laufen?
Ob du eine Statemachine aufbaust oder nicht hängt von deiner Anwendung
ab. Zwingend notwendig ist das nicht.
Dietmar schrieb:> Hast du den Zugriff jetzt fehlerfrei laufen?
ja
Ich habe keine Abstürze mehr.
Ich bin immer noch erstaunt was man mit Labview machen kann.
Hallo Dietma,
ich habe eine kurze Frage.
Ich habe einen state machine mit labview erstellt.
Allerdigns ohne Vi destroy_base einzusetzen.
Wann soll ich das einsetzen ohne labview abtürzen zu lassen?
Danke
Spät gesehen,
du solltest dir in deiner Statemachine einen state schaffen in dem du
aufräumst, hier auch das VI destroy_base aufrufen. Danach darfst du halt
nicht mehr auf die DLL zugreifen.
Danach solltest du das VI mit der Statemachine auch beenden. Eigentlich
darf dann keine Fehlermeldung mehr kommen.
Gruß
Dietmar
Hallo Dietmar,
danke für die Antwort.
Ich habe auch in der Statemachine einen state erstellt, wo ich halt nur
das VI destory_base aufrufe.
Sobald ich dieses state aufrufe stürtz Labview ab.
Bitte seh Anhang.
Danke in voraus
Hallo,
Das Labview Abstürz bekomme ich nicht immer.
Ich weiss es nicht woran es liegen kann.
Das Problem lässt sich nicht reproduzieren.
Es tritt ein aber halt nicht immer.