Mehrdimensionale Arrays an Dll übergeben
-
Servus,
guter Vorschlag Geo, leider funktioniert er nicht.
zur Abwechslung mal n bissl Code:class CJCDLL{ private: typedef __declspec(dllimport) char MusterT[1344][10000]; typedef bool (DLLFUNCTION)(char *Filename, bool Bonas_AutoDLL, byte Lang, int X, int Y, MusterT Muster, int X_SizeDLL, int Y_SizeDLL, char *Fehler); DLLFUNCTION *pDllFunction; HINSTANCE hInstance; public: CJCDLL(); ~CJCDLL(); //in der Methode rufe ich den Quatsch auf, d.h. die Parameter der Methode gehen an die dll bool CallDllFunction(char *Filename, bool Bonas_AutoDLL, byte Lang, int X, int Y, MusterT Muster, int X_SizeDLL, int Y_SizeDLL, char *Fehler); };
die dll wird wunderbar aufgerufen, sieht man ja an der dll-import-Message zur Laufzeit. Dann gibt es einen Integer-Überlauf in der Dll und daraus folgend eine "Abnormal Programm-Termination" .
Wenigstens frißt er jetzt die großen Arrays schon mal. Besser als nix. Aber mit der dll (die übrigens unter einem anderen Programm(Delphi) läuft) wirds wohl an der Stelle nix werden.
__declspec(pascalimplementation), und die anderen Sachen aus der Hilfe hab ich schon probiert, negativ.Danke dir noch mal für deine Hilfe.
Ciao.
-
private:
typedef __declspec(dllimport) char MusterT[1344][10000];Eine Importdeklaration für eine Membervariable habe ich bisher noch nicht gesehen.
Wenn die Klasse in der DLL vorkommt, musst du die Klasse als Importtyp deklarieren, nicht die Einzelteile.
-
Hi,
funktioniert aber. (kleiner Scherz)
Ehrlich gesagt, bin ich noch nicht so lange bei bcb unterwegs (eher schon bei QT) und weiß mit dem Macro (oder Funktion???) "__declspec" nicht viel anzufangen. Sollte ich damit vielleicht die Dll irgendwie als irgendwas bekanntmachen ? mfg
-
Nachtrag:
Das "typedef" davor iss eigentlich nur eine Notlösung, weil sonst gar nicht durchkompiliert wird. Es wird sonst der Typ der Variable "Muster" vermisst.
-
Servus nochmal,
habe noch mal ein Minütchen Zeit gefunden. Wenn ich dich recht verstehe, meinst du das etwa so:
class CJCDLL{ private: typedef char MusterT[1344][10000]; __declspec(dllimport) bool (DLLFUNCTION)(char *Filename, bool Bonas_AutoDLL, byte Lang, int X, int Y, MusterT Muster, int X_SizeDLL, int Y_SizeDLL, char *Fehler); // Hier meckert der Compiler, er erwartet einen Typnamen DLLFUNCTION *pDllFunction; HINSTANCE hInstance; : : : };
Beim deklarieren des Zeigers bricht er ab(aber nur mit declspec(..) ).
Den Zeiger *pDllFunction brauche ich, um später im Konstruktor folgenden Aufruf zu machen:pDllFunction = (DLLFUNCTION*)::GetProcAddress( (HMODULE)hInstance,"FunktionsName");
Schließlich brauche ich ja einen Zeiger der den Rückgabewert von GetProcAdress aufnimmt.
Bei einer mit typedef deklarierten Dll-Funktion (siehe oben) funktioniert es, bis auf den Integerüberlauf. Vielleicht liegts ja wirklich an der dll (die unter Delphi geht)?mfg
-
nee, meinte ich nicht.
Zwischenfrage: Wie sieht denn die Pascal-Deklaration der Klasse aus?
-
alles was ich habe sind die Typvereinbarungen in einem Delphiprogramm, wo das Teil aufgerufen wird und läuft.
MusterT=array[1..1344,1..10000] of byte; TSaveFunktion = function(FilenameDLL:PChar; Bonas_AutoDLL:Boolean; LangDLL :Byte; X :Integer; Y :Integer; Var MusterDLL:MusterT; Var X_SizeDLL:Integer; Var Y_SizeDLL:Integer; Var FehlerDLL:PChar) :Boolean;
Dann wird irgendwo (in ein. Prozedur) eine Variable des Typs erstellt:
SaveFunktion : TSaveFunktion; FuncPtr : TFarProc; erfolg : Boolean;
Dann wird die Verbindung zur dll mit LoadLibrary und GetProcAddress hergestellt, wie in C++,
Auf FuncPtr steht das Ergebnis von GetProcAddress;@SaveFunktion := FuncPtr; erfolg:=Savefunktion(FileName, true, 0, 0, 4, Muster, y_max, x_max, Fehlerstr);
Mehr hab ich leider nicht. Vielleicht hilft es dir aber trotzdem weiter.
Danke.
-
Und warum willst du eine Klasse daraus machen?
Das sieht doch nach einzelnen Elementen aus.
extern __declspec(dllimport) char MusterT[1344][10000]; __declspec(dllimport) bool funktionsname(char *Filename, bool Bonas_AutoDLL, char Lang, int X, int Y, char *Muster, int X_SizeDLL, int Y_SizeDLL, char *Fehler);
Dass MusterT by value übergeben scheint mir fragwürdig, da es dafür zu gross ist.
Schreib doch jedes Wort in eine eigene Zeile, damit du siehst, welches Wort den Fehler verursacht.
[ Dieser Beitrag wurde am 12.03.2003 um 16:46 Uhr von Geo editiert. ]
-
Servus,
Klasse oder nicht, das Problm liegt, denk ich, ganz wo anders.
Die Funktion wird zwar mit declspec... bekannt gemacht, aber wo mach ich folgendes:pDllFunction = (DLLFUNCTION*)::GetProcAddress(
(HMODULE)hInstance,"FunktionsName");So stell ich normalerweise die Verbindung zu der entsprechenden Funktion her. Und wie soll ich mir den Zeiger darauf besorgen, wenn ich nicht mal einen Typ deklariert habe, aus dem ich dann einen Zeiger des Typs basteln kann??. Irgendwie muß der Dll doch mitgeteilt werden, welche Funktion verwendet wird. Wahrscheinlich bin ich mächtig auf dem Holzweg, oder wir reden aneinander vorbei.
Inzwischen hat sich die Aufgabe ins Delphi-Lager zurückgezogen. Aber früher oder später kann ja das Problem wieder mal auftauchen, deshalb bin ich nach wie vor (wenn die Zeit es zuläßt) an der Sache dran.
Danke erst mal für deine Hilfe. Wenn dir spontan noch was einfällt, bin ich dankbar.mfg
-
Um eine DLL Funktion benutzen zu können, müssen zwei Dinge erfüllt sein.
1. Der Compiler muss wissen, wie die Funktion aufzurufen ist, das machst du mit der __declspec Deklaration
2. Der Compiler muss die Adresse der Funktion kennen, das machst du
entweder A) zur Linkzeit durch einbinden einer .lib - Datei
oder zu Laufzeit (dynamisch) mit LoadLibrary und GetProcAddress irgendwann vor dem Aufruf der Funktion.
[ Dieser Beitrag wurde am 18.03.2003 um 08:14 Uhr von Geo editiert. ]
-
Nr1 ist ja nun erfüllt.
Nr 2, Plan A scheidet aus, weil ich keine lib habe.
Plan B würde mich brennend interessieren, zumal ich ja zu Anfang die Dll wunderbar angebunden habe. Seit __declspec geht das aber nicht mehr. Mit anderen Worten: Plan B hab ich schon gemacht, gibt aber in der Dll einen Fehler.in obigem Code (der erste im Thread) ist nur folgende Zeile anders:
// typedef __declspec(dllimport) char MusterT[1344][10000]; // wird ersetzt durch: typedef char MusterT[1344][10000];
aber in der dll hat er einen Integerüberlauf...(ich wiederhole mich)
sonst gehts (nach Plan B, eigentlich mein urspr. Plan, der aber nicht funktioniert)
Ich dreh mich im Kreis..
-
Falls du Borland BCB benutzt, kannst du implib.exe benutzen, um die .lib Datei zu erstellen.
Der Integerüberlauf hat nichts damit zu tun, dass es in einer DLL ist. Du weist einer int Variablen nur einen Wert aus einer Float oder Double Zahl zu, die numerisch zu groß ist.
[ Dieser Beitrag wurde am 20.03.2003 um 17:25 Uhr von Geo editiert. ]
-
implib.exe : werd das mal probieren, danke für den Tip.
Der Integerüberlauf tritt in der Dll auf, darauf habe ich aber keinen Einfluß. Schließlich kann ich die Daten nur so übergeben, wie in dem Beispiel mit dem Delphi-Code. Kann mich da nur nach der Signatur richten.
Aber trotzdem vielen Dank für deine Bemühungen. Leider komm ich in der nächsten Zeit nicht dazu, mich nochmal mit der Sache auseinanderzusetzen (die konnte ich ja erfolgreich aus dem Projekt kicken ;-)). Vielleicht holt mich ja das Thema trotzdem noch mal ein...
Ciao.