Autor |
Beitrag |
kurzer
Hält's aus hier
Beiträge: 11
Debian Linux Woody r3.0 Kernel 2.4.18k7; WinXP Home
MinGW C++
|
Verfasst: Do 24.07.03 18:02
Moin ihr!
Um diesen vielen Threads ein Ende zu setzten: Hier ist das eigentlich Problem.
Punkt 1: mimi und ich arbeiten am selben Projekt
Punkt 2: Es geht hier um die Nutzung einer DLL, die ich geschrieben hab, die auch super funktioniert.
Punkt 3: Das Problem ist, ich hab die DLL in C++ geschrieben und nun müssen spezielle Header nach Pascal übersetzt werden.
Header PAC_EXPORTS.H:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| #ifndef PAC_EXPORTS #define PAC_EXPORTS
#include "pac_types.h" // pac-types
// constructors PAC_BasicAI PAC_CreateBasicAI (PAC_POINT Position, PAC_ISFREEATPOINTXY ifapxy, bool Enabled = false); PAC_BasicAI PAC_CreateBasicAI (int x, int y, PAC_ISFREEATPOINTXY ifapxy, bool Enabled = false);
// destructor void PAC_DestroyBasicAI (PAC_BasicAI AI);
// Let's GO! void PAC_MoveBasicAI (PAC_BasicAI AI, int Steps);
// to change/get some data void PAC_SetPosition (PAC_BasicAI AI, int x, int y); void PAC_SetPosition (PAC_BasicAI AI, PAC_POINT Position); PAC_POINT PAC_GetPosition (PAC_BasicAI AI);
void PAC_SetEnabled (PAC_BasicAI AI, bool Enabled); bool PAC_GetEnabled (PAC_BasicAI AI);
void PAC_SetIsFreeFunc (PAC_BasicAI AI, PAC_ISFREEATPOINTXY ifapxy);
#endif // PAC_EXPORTS |
Header: PAC_TYPES.H
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| #ifndef PAC_TYPES #define PAC_TYPES
// PAC_POINT-type typedef struct { int x; int y; } PAC_POINT;
// direction-types typedef enum { PAC_DIRNONE = 0, PAC_DIRLEFT, PAC_DIRUP, PAC_DIRRIGHT, PAC_DIRDOWN } PAC_DIR; const PAC_POINT PAC_DIRS[5] = { { 0, 0 }, {-1, 0 }, { 0,-1 }, { 1, 0 }, { 0, 1 } };
// tool-tip missing *g* typedef bool (*PAC_ISFREEATPOINTXY)(int, int);
// PAC_BasicAI-Type typedef void* PAC_BasicAI;
#endif // PAC_TYPES |
Jeder Üersetzungsversuch wurde zwar von Delphi kompiliert, jedoch kommt beim Start eines Testprogramms die Fehlermeldung, dass die Anwendung nicht richtig initialisiert werden kann, was mir sagt, dass die Funktionen aus der DLL nicht mit den richtigen Parametern aufgerufen werden.
Wenn jemand mitmachen will, diesen code zu übersetzen, kann er das gerne machen und hier Lösungen posten!
Vielen Dank im voraus 
_________________ Grüße, kurzer
|
|
AndyB
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: Do 24.07.03 19:59
kurzer hat folgendes geschrieben: | Jeder Üersetzungsversuch wurde zwar von Delphi kompiliert, jedoch kommt beim Start eines Testprogramms die Fehlermeldung, dass die Anwendung nicht richtig initialisiert werden kann, was mir sagt, dass die Funktionen aus der DLL nicht mit den richtigen Parametern aufgerufen werden. |
Falscher Rückschluss. Das bedeutet, dass die Namen der Funktionen nicht in der DLL gefunden werden.
C++ benutzt name mangling. Dadurch werden die Parametertypen in den Funktionsnamen hineinkodiert. Du musst bei der Delphi Header-Übersetzung somit diese exportierten Namen benutzen. (Ich wiederhole mich irgendwie)
Borland C++:
Delphi-Quelltext
Delphi-Quelltext 1:
| function myFunc(int a): Integer; cdecl; external MyLib name 'myFunc$qi'; |
_________________ Ist Zeit wirklich Geld?
|
|
kurzer 
Hält's aus hier
Beiträge: 11
Debian Linux Woody r3.0 Kernel 2.4.18k7; WinXP Home
MinGW C++
|
Verfasst: Do 24.07.03 20:11
Das ist eine große Hilfe. Nur, woher weiß ich denn nu genau, wie der Name lautet? Kann man das irgendwo nachlesen? Ich meine, es sind ja nicht immer einfache integer Parameter.
Zitat: | (Ich wiederhole mich irgendwie) |
Oha! Sry, aber muss ich übersehen haben.
_________________ Grüße, kurzer
Zuletzt bearbeitet von kurzer am Do 24.07.03 20:49, insgesamt 1-mal bearbeitet
|
|
AndyB
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: Do 24.07.03 20:36
kurzer hat folgendes geschrieben: | Mensch macht Delphi seltsame Sachen. Ich meine, schließlich trifft man beim dynamischen Laden der Dlls nicht auf dieses Problem. |
Doch bei C++ DLLs muss man immer damit rechnen, dass der Programmierer ein umschließendes
Delphi-Quelltext
vergessen oder absichtlich nicht hineingeschrieben hat. Des weiteren sollten DLLs unter Windows stdcall benutzen. Aber C/C++ Programmierer sind da eigen.
Zitat: | Das ist eine große Hilfe. Nur, woher weiß ich denn nu genau, wie der Name lautet? Kann man das irgendwo nachlesen? Ich meine, es sind ja nicht immer einfache integer Parameter. |
Windows 95 hatte da so eine QuickView Funktion, die die exportierten und importierten Funktionen aufgelistet hat. Bei den anderen BSs muss man sich mit Dritt-Programmen weiterhelfen. Da gibt es z.B. Dependency View
_________________ Ist Zeit wirklich Geld?
|
|
kurzer 
Hält's aus hier
Beiträge: 11
Debian Linux Woody r3.0 Kernel 2.4.18k7; WinXP Home
MinGW C++
|
Verfasst: Do 24.07.03 20:48
Ok! Das mit dem extern "C" habe ich auch gerade erst erfahren (News Groups sind doch was feines)
Damit haben sich jetzt einige Dinge geklärt und mein Satz über Delphi darf gestrichen werden.
_________________ Grüße, kurzer
|
|
kurzer 
Hält's aus hier
Beiträge: 11
Debian Linux Woody r3.0 Kernel 2.4.18k7; WinXP Home
MinGW C++
|
Verfasst: Do 24.07.03 22:02
AndyB, ich bitte dich mir weiter zu helfen. Ich hab nun 'extern "C" {...}' eingebaut, doch funktionieren tut immer noch nix.
Dank extern "C" habe ich jetzt eigentlich das name mangling abgeschaltet .. dachte ich.
Momentan sieht die pac-exports unit so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| unit pac_exports;
interface
uses pac_types; function PAC_CreateBasicAIP (Position: PAC_POINT; ifapxy: PAC_ISFREEATPOINTXY; Enabled: boolean): PAC_BasicAI; {$IFDEF WIN32} stdcall {$ENDIF}; external 'PAC_BasicAI'; function PAC_CreateBasicAII (x, y: integer; ifapxy: PAC_ISFREEATPOINTXY; Enabled: boolean): PAC_BasicAI; {$IFDEF WIN32} stdcall {$ENDIF}; external 'PAC_BasicAI';
procedure PAC_DestroyBasicAI (AI: PAC_BasicAI); {$IFDEF WIN32} stdcall {$ENDIF}; external 'PAC_BasicAI';
procedure PAC_MoveBasicAI (AI: PAC_BasicAI; Steps: integer); {$IFDEF WIN32} stdcall {$ENDIF}; external 'PAC_BasicAI';
procedure PAC_SetPositionP (AI: PAC_BasicAI; Position: PAC_POINT); {$IFDEF WIN32} stdcall {$ENDIF}; external 'PAC_BasicAI'; procedure PAC_SetPositionI (AI: PAC_BasicAI; x, y: integer); {$IFDEF WIN32} stdcall {$ENDIF}; external 'PAC_BasicAI'; function PAC_GetPosition (AI: PAC_BasicAI): PAC_POINT; {$IFDEF WIN32} stdcall {$ENDIF}; external 'PAC_BasicAI';
procedure PAC_SetEnabled (AI: PAC_BasicAI; Enabled: boolean); {$IFDEF WIN32} stdcall {$ENDIF}; external 'PAC_BasicAI'; function PAC_GetEnabled (AI: PAC_BasicAI): boolean; {$IFDEF WIN32} stdcall {$ENDIF}; external 'PAC_BasicAI';
procedure PAC_SetIsFreeFunc (AI: PAC_BasicAI; ifapxy: PAC_ISFREEATPOINTXY); {$IFDEF WIN32} stdcall {$ENDIF}; external 'PAC_BasicAI';
implementation
end. |
_________________ Grüße, kurzer
|
|
AndyB
      
Beiträge: 1173
Erhaltene Danke: 14
RAD Studio XE2
|
Verfasst: Fr 25.07.03 00:48
kurzer hat folgendes geschrieben: | Dank extern "C" habe ich jetzt eigentlich das name mangling abgeschaltet .. dachte ich. |
Das kannst du ja nachprüfen mit dem oben verlinkten Programm.
Willst du auch Windows 3.1x unterstützen?
Zitat: | external 'PAC_BasicAI'; |
Hat die DLL auch eine Dateierweiterung?
_________________ Ist Zeit wirklich Geld?
|
|
kurzer 
Hält's aus hier
Beiträge: 11
Debian Linux Woody r3.0 Kernel 2.4.18k7; WinXP Home
MinGW C++
|
Verfasst: Fr 25.07.03 13:21
Zitat: | Willst du auch Windows 3.1x unterstützen? |
Jupp! Spricht was dagegen?
Zitat: | Hat die DLL auch eine Dateierweiterung? |
Die muss man nicht angeben. Schreibfaule werden ja immer mehr unterstützt
Das Problem ist gelöst! Man sollte erstmal lernen, wie man mit seinem Compiler eine DLL erzeugt.  Der MinGW ist bei dem Thema etwas eigen - is ja schließlich eine GCC Portierung.
@mimi: Die Übersetzung ist komplett und nutzbereit.
_________________ Grüße, kurzer
|
|
|