DLL Funktionsaufruf mit Parametern crashed
-
Hi, da ich grad neu hier bin hoffe ich richtig gelandet zu sein.
Mein Funktionsaufruf ohne Parameter und Rückgabe nur eines integer-Wertes geht. Nur der Aufruf einer alten FORTRAN DLL schlägt fehl.
Rein geht 12,12334 54,1234 und als String kommt "54N0203012E0304" zurück. bzw soll zurückkommen.Der Aufruf mit z.B. Centura Team Developer in der Version 2005 haut ohne Fehler hin. Nur die neuen Programmierbänke ab 5.1 und 6.0 unterstützen keine alten ANSI Strings mehr. Deswegen hier der erste Versuch einer Wrapper-DLL in C++.
siehe Quelltext->
#include "stdafx.h" #include <windows.h> #include <afxres.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <dos.h> //*** KOO_TO_STRING Schnittstelle zu FORTRAN DLL definieren typedef (*KOO_TO_STRING_t)(double&,double&,int&, char[15]); KOO_TO_STRING_t KOO_TO_STRING; //*/ int i; BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { //*** Für einmaliges Laden der Dll und für Aufrufzähler etc. //************** Dll holen -> Handle hLib HMODULE hLib = LoadLibrary("FortranDll.dll"); //Adresse der Funktion holen KOO_TO_STRING = (KOO_TO_STRING_t) GetProcAddress (hLib, "KOO_TO_STRING"); i=100; return TRUE; } #define DllExport extern "C" __declspec( dllexport ) #define WINAPI __stdcall // Interface DllExport int WINAPI fDllKOO_TO_STRING (double&,double&,int&, char[15]); //********************** Implementation DllExport int WINAPI fDllKOO_TO_STRING (double& d1,double& d2,int& i1, char s1[15]) { // !!! Hier stürtzt die DLL ab ?? // Parameter alle receive (*KOO_TO_STRING)(d1,d2,i1,s1); //Dll wegschmeißen //bReturn = FreeLibrary(hLib); return i--; }edit, für Herrn Bloob verschönert, die Frage steht im Quelltext
-
Was genau ist deine Frage? Warum dein typedef nicht compliert oder ob wir deinen Coding-Style genauso schrecklich finden wie du?
//************** Dll holen -> Handle hLib #define Rostock "Rostock.dll" HMODULE hLib = LoadLibrary(Rostock);Was soll der Kommentar, man sieht doch was hier passiert? Und warum der Dateiname als Makro?
return i--;Was i sein soll dokumentierst du komischerweise nicht, obwohl sich der Sinn nirgendwo erschließen lässt. Außer in einem entfernten Kommentar, wo du etwas von einem Aufrufzähler erzählst. Der Zusammenhang ist aber rein geraten.
Vielleicht aber auch was ganz anderes?
-
das Problem scheint in der Zeile
// !!! Hier stürtzt die DLL ab ?? // Parameter alle receive (*KOO_TO_STRING)(d1,d2,i1,s1);zu stecken. Da stürzt das aufrufende Programm ab. Sorry für die
Form, und das "i" war oben als int deklariert, ist beim Zusammenschieben verschütt gegangen.Wie rufe ich o.g. Funktion richtig auf? laut typedef??
-
Mir ging es nicht darum, ob du irgendwas schöner für mich machst oder nicht. Das ist dein Quelltext und du musst ihn lesen können. Aber ich denke du merkst selber, dass dir die Struktur fehlt?
Zu deinem Problem, du bist dir sicher, dass dieser Quelltext compiliert? Soweit ich weiß, gibt es in C keine Referenzen. Der typedef ist Unsinn. Um nur die groben Schnitzer zu nennen.typedef myint; // das hast du geschrieben typedef int myint; // das wolltest du schreibenAlso selbst wenn dein Compiler das akzeptiert, würde ich mich nicht drauf verlassen, dass das passiert, was du denkst.
Ich werd von dir sicher als hochnäsig und arrogant abgetan, aber ich denke, dass du dir hier zuviel vorgenommen hast.
Du kannst ja einfach mal die Original-Deklaration von KOO_TO_STRING posten. Dann kann dir jemand den richtigen typedef geben und du kannst erstmal weiter arbeiten.
-
Wenn ich eine Funktion in der Art schreibe, die mir nur einen Integer-wert zurück gibt, haut ja alles hin. Nur der Funktionsaufruf mit den Parametern scheint nicht zu gehen.
Wieso soll der Quelltext nicht funktionieren?
1. Meine Applikation (Gupta-Form-window) ruft (TeamDeveloper 6.0)
2. Die Dll "XXXX.dll" auf und diese ruft die Fortran-DLL (C++ 6.0)
3. FORTRANDLL.DLL auf (irgend ein alter FORTRAN-Compiler)verstehe deine Bedenken nicht, hmm
hier das Interface in Centura, welches ANSI-compatibel hinhaute:
! Funktion KOO_TO_STRING
! Interface:
! 1. DoublePrecision LAENGE, Eingabe
! 2. DoublePrecision BREITE, Eingabe
! 3. Integer Fehlerwert (0 = kein Fehler, 1 = Fehler), Ausgabe
! 4. String mit genau 15 Zeichen (Feld 4C, Format: "005E200050N3000"), Ausgabe
Function: KOO_TO_STRING
Description:
Export Ordinal: 0
Returns
Parameters
Receive Number: LPDOUBLE
Receive Number: LPDOUBLE
Receive Number: LPINT
Receive String: LPSTRIch glaube Fortran terminiert die String NICHT mit einer "\x00"
So ist das, mehr habe ich nicht

-
torama schrieb:
Wenn ich eine Funktion in der Art schreibe, die mir nur einen Integer-wert zurück gibt, haut ja alles hin. Nur der Funktionsaufruf mit den Parametern scheint nicht zu gehen.
Zwischen Schein und Sein liegen Welten. Da du hier Funktionen deklarierst, die dein Compiler nicht kennt, wird er dich auch nicht auf Fehler hinweisen.
torama schrieb:
Wieso soll der Quelltext nicht funktionieren?
Weil bei deinem typedef der Typ fehlt, hab ich dir aber oben schon geschrieben. Auch gibt es keine Referenzen in C, welchen Sinn hat dann das C-Interface?
Ich würde mal so etwas probieren:
typedef void (*KOO_TO_STRING_t)(double *, double *, int *, char *);Wobei hieraus weder hervorgeht, ob ein Long-Pointer aus Fortran identisch zum C-Pointer und ob der Aufbau von Double identisch ist. int dürfte soweit passen und char sollte bei ASCII-Zeichen auch keine Probleme bereiten.
-
probier ich morgen mal aus...
-
(*KOO_TO_STRING)(d1,d2,i1,s1);
KOO_TO_STRING(d1,d2,i1,s1);und bitte:
KOO_TO_STRING_t KOO_TO_STRING = NULL;
...
if(KOO_TO_STRING) KOO_TO_STRING(d1,d2,i1,s1);Nach neuer "Sicherheitspolitik" vom MS wird es zukünftig wohl besser sein DLL's mit LoadLibrary mit vollem Pathname anzugeben. Auf die Windows Suchreihenfolge wenn kein Verzeichnis angegeben ist, wird wohl kein verlass mehr sein.
-
Bist du sicher, dass du im richtigen Forum bist? Ich seh nur C und WinAPI - mit C++ hat dein Quelltext garnichts zu tun. (vor allem die eingebundenen Header nicht)
-
Habe jetzt mal alles in C++ minimiert und probiert. Hier meine DLL die aus der anderen DLL aufgerufen werden soll:
// DLL die von der anderen Dll aufgerufen wird #include "stdafx.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } #define DllExport extern "C" __declspec( dllexport ) #define WINAPI __stdcall // Interface DllExport int WINAPI Test (double&); // Implementation DllExport int WINAPI Test (double& d1) { int i = 7; i = (int)d1 + i; return i; }Diese DLL funktioniert definitiv!!
und hier die aufrufende DLL:// Diese Dll ruft die Test-Funktion in der xyz.dll auf //*** Test Schnittstelle zur DLL definieren typedef int (*Test_t)(double&); Test_t Test; //*/ BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { //************** Dll holen -> Handle hLib HMODULE hLib = LoadLibrary("xyz.dll"); //Adresse der Funktion holen Test = (Test_t) GetProcAddress (hLib, "Test"); return TRUE; } #define DllExport extern "C" __declspec( dllexport ) #define WINAPI __stdcall // Interface DllExport int WINAPI fDllTest (double&); // Implementation DllExport int WINAPI fDllTest(double& d1) { int i = 0; // Aufruf der anderen DLL -> Absturz?? i=Test(d1); return i; }Wenn ich die obere DLL ohne Parameter definiere und aufrufe bekomme ich den
Integer-Rückgabewert korrekt zurück, nur mit Parameter gehts nicht. Was ist hier faul?
-
typedef int _stdcall (*Test_t)(double&);
-
matze555 schrieb:
typedef int _stdcall (*Test_t)(double&);
das mag der Compiler gar nicht --Syntaxfehler
-
torama1 schrieb:
matze555 schrieb:
typedef int _stdcall (*Test_t)(double&);
das mag der Compiler gar nicht --Syntaxfehler
die sau ... microschrott? dann versuch
typedef int (_stdcall *Test_t)(double&);da wird aber Dein Problem liegen. Wenn die DLL mit z.B. cdecl als Standard Aufrufkovention compiliert wird, all Deine Funktionen aber manuell _stdcall setzen, dann geht der Compiler bei Deinem Funktionspointer wieder cdecl aus. Beim Aufruf/Rückkehr passt dann nix mehr auf'm Stack.
-
ja was mach ich denn nun? Wie gesagt ohne Parameterliste geht der Hokus-Pokus.
Es wird doch jemanden geben, der schon mal ne DLL aus einer DLL aufgerufen hat und das auch mit Parameterliste und Strings usw.gibts doch gar nicht.
-
// Interface DllExport int WINAPI fDllTest (double&); // Implementation DllExport int WINAPI fDllTest(double& d1) { int i = 0; // Aufruf der anderen DLL -> Absturz?? i=Test(d1); return i; }Wenn in Gupta TD ein Parameter als Receive Param angegeben wird, muß im Dll-Interface ein Pointer genommen werden. Also
DllExport int WINAPI fDllTest(double* d1)Ansonsten geht das nur zufällig und kracht spätestens beim Durchreichen an die nächste Funktion.
Ausserdem glaube ich nicht, das _cdecl-Schnittstellen überhaupt Referenzen kennen, da C sie ja nunmal auch nicht kennt. (Von Fortran mal ganz abgesehen)
-
Alle meine C++ - DLLs benutzen die _cdecl - Deklaration. Das haut auch mit Parametern und Receive Parameter, String usw. super hin bei Einbindung in den TeamDeveloper.
Hat den jemand mal die 2 Minuten Zeit die 2 Projekte zu cutten und mal selber auszuprobieren. Evtl. ist es ja ganz trivial.
Oder es liegt wirklich nur am UNICODE den der TD nicht mehr kann. Ich werde mal mit niedriger Version 4.0 oder so noch mal probieren.naja danke trotzdem erst mal