(18.09.2015 18:38 )galilio schrieb: (17.09.2015 17:35 )galilio schrieb: Hallo Rolf,
Danke für deinen Tipp.
Ich habe es jetzt meine Dammy Projekt so angepasst:
Header File:
Code:
#pragma once
#ifdef __cplusplus
#endif
extern "C"__declspec(dllexport) void* createWrapper(double a, double b);
extern "C"__declspec(dllexport) void destoryWrapper(void *instance);
extern "C"__declspec(dllexport) double Add(void *instance, double a, double b);
.....
#ifdef __cplusplus
#endif
Source Code:
Code:
#include "stdafx.h"
#include "MyClass.h"
#include "C_DllWrapper.h"
extern "C"__declspec(dllexport) void* createWrapper(double a, double b)
{
return new MyClass(a, b);
}
extern "C"__declspec(dllexport) void destoryWrapper(void *instance)
{
MyClass *myClass = static_cast<MyClass*>(instance);
delete myClass;
}
extern "C"__declspec(dllexport) double Add(void *instance, double a, double b)
{
MyClass *myClass = reinterpret_cast<MyClass*>(instance);
return myClass->Add(a, b);
}
....
static_cast<> und reinterpret_cast<> brauche ich um das Pointer Objekt MyClass
zu casten sonst bekomme ich stets eine Fehlermeldung
Diesem Code kann ich mit Visual Studio und LabVIEW in debug Modus durchlaufen.
Es ist keine Fehler aufgetreten.
Nun habe ich Verständnis Frage:
Als erste muss ich eigentlich das Objekt MyClass erst erzeugen können und das tue in dem ich
die Funktion createWrapper(double a, double b) aufrufe (damit wird das Objekt erzeugzt).
Bis hier ist alles okay.
Wenn ich diese Funktion z.B. :
header Files:
Code:
extern "C"__declspec(dllexport) double Add(void *instance, double a, double b);
Source Files:
Code:
extern "C"__declspec(dllexport) double Add(void *instance, double a, double b)
{
MyClass *myClass = static_cast<MyClass*>(instance);
return myClass->Add(a, b);
}
aufrufe, wie kann ich meinem Objekt (Pointer) "MyClass" auf LabVIEW Seite für dieses Funktion bekannt machen?
Kommt drauf an was Du hier meinst. Wenn es nur darum geht dies lauffähig zu machen dann sage LabVIEW halt einfach dass es ein pointer sized integer ist:
Code:
void *instance Pointer to some memory location
sagt es ja eigentlich schon. Es ist ein Pointer. LabVIEW kennt selber keine Pointer aber ein Pointer ist eigentlich einfach eine Integernummer. Vor LabVIEW 2009 war das immer equivalent zu einem 32 Bit Integer. Seit LabVIEW 2009 gibt es auch eine 64 Bit Version sodass das nicht mehr stimmt und daher hat LabVIEW in der Call Library Node hinzugelernt und kennt jetzt auch einen pointer sized Integer der je nach Bitgrösse von LabVIEW korrekt übergeben wird. Auf dem LabVIEW Diagram ist es IMMER ein 64 Bit Integer (das KGV von 32 und 64).
Wenn Du da ein richtiges seperates Kontrol haben willst, so dass ein Dummyuser nicht per Unglück seinen Geburtstag als MyClass Pointer eingeben kann und Deine DLL dann grausam crasht, dann hast Du ziemlich grosses Pech. Der alte Trick mit der Datalog Refnum mit einem speziellen Enum drin, sodass Du eine spezielle Refnum bekommst die nur zu sich selber verbunden werden kann, funktioniert leider nicht mehr. Da LabVIEW Refnums immer 32 bit sind, würdest Du so Deine 64 Bit Pointer korrumpieren wenn Du sie als LabVIEW refnum behandeln möchtest. Und nein, Refnums heutzutage dazu zu verwenden weil Deine DLL eh nur als 32 Bit DLL kompiliert wird ist keine gute Option mehr. Windows 10 ist nur noch 32 Bit wenn es von einer alten 32 bit Installation geupgradet wird ansonsten ist es nur noch als 64 Bit Version erhältlich. In ein paar Jahren bist Du ein Freak wenn Du 32 Bit Applikationen bei einem Kunden installieren willst.
Der saubere Workaround hier wäre wohl eine LabVIEW Klasse. Der Pointer wird dann als private data der Klasse behandelt und Du schreibst für jede Methode in Deiner DLL eine Klassenmethode als VI. somit kommt der Dummyuser nicht mehr an den Pointer und kann ihn nicht ungültig machen.