In BCB geschriebene Objekt unter Delhpi verwenden???
-
Ich habe in BCB ein einfaches Testobjekt geschrieben das Ein Haus des Nickolaus auf das Fenster malt. Dazu kriegt der Konstruktor ein Pointer auf TCanvas übergeben, den er in einer private variable speichert und sobald man die Funktion Draw() aufruft wird das Haus gemalt.
Dieses Objekt würde ich jetzt gerne unter Delphi verwenden...
Das erste Problem is ja schon das Delphi keinen c++-compiler dabeihat.
Also hab ich erstmal angefangen eine DLL zu schreiben, die eine Instanz des Objekts erzeugt und die Adresse zurückgibt. Das Objekt stammt von einer rein virtuellen Klasse ab und die Klasse ist im Programm bekannt und darüber kann ich dann ja auf die Funktionen des Objekts zugreifen wenn ich ne Instanz hab (genauso wie man das auch im BCB-tutorial nachlesen kann).Der Versuch das Objekt über die in C++ geschriebene DLL in ein Delphiprogramm zu importieren is gleich mal heftig fehlgeschlagen. Ich hab erstmal die selbe virtuelle Klasse im Delphiprogramm deklariert von der auch das Objekt in der DLL abstammt. Ich krieg auch den Pointer auf die Instanz aber der Zugriff funzt nicht. Irgendwie scheint er die falsche einsprungsadresse zu errechnen.
(Es wird von allen Funktionen stdcall verwendet also da liegt der Fehler nicht)Die einzige erklährung die mir für das Problem einfällt ist, Das die virtuelle Mutterklasse in Pascal sich von der in C++ unterscheidet.
kann ich dem C++Builder irgendwie beibringen, dass die Klasse aussehen soll wie die, die in Pascal geschrieben is??
-
nochmal ein kurzes Beispiel wie ich das meine. Hier wird zwar nich ein Heus des Nikolaus gezeichnet aber das prinzip is das Selbe:
Erstmal die DLL:
das Virtuelle Objekt TRechner:
TRechner.h#ifndef TRECHNER_H #define TRECHNER_H #include <vcl.h> class TRechner : public TObject { public: virtual int __stdcall rechenart1 (int &a, int &b) =0; virtual int __stdcall rechenart2 (int &a, int &b)= 0; } ; #endifdann
dll_main.cpp#include <windows.h> #include "TSRechner.h" #pragma argsused BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved) { return 1; } //--------------------------------------------------------------------------- extern "C" __declspec(dllexport) TSRechner* __stdcall GetInstance (void) { return new TSRechner(); }TSRechner.h Das Objekt was exportiert werden soll!
//--------------------------------------------------------------------------- #ifndef TSRechnerH #define TSRechnerH #include "TRechner.h" //--------------------------------------------------------------------------- class TSRechner : public TRechner { public: int __stdcall rechenart1 (int &a, int &b); int __stdcall rechenart2 (int &a, int &b); } ; #endifund zu guter letzt die Implementation
//--------------------------------------------------------------------------- #pragma hdrstop #include "TSRechner.h" //--------------------------------------------------------------------------- #pragma package(smart_init) int __stdcall TSRechner::rechenart1 (int &a, int &b) { return a+b; } int __stdcall TSRechner::rechenart2 (int &a, int &b) { return a*b; }So das war die DLL. In delphi hab ich erstmal die virtuelle Klasse implementiert sowie zwei Pointer weil delphi die Schreibweise ^TYP in Funktionsdeklarationen irgendwie nich mag
type TRechner = class function Rechenart1 (x,y : Integer):Integer;virtual;stdcall;abstract; function Rechenart2 (x,y : Integer):Integer;virtual;stdcall;abstract; end; type pTRechner = ^TRechner ; type InstanceFunc = function :pTRechner;stdcall;Und dann wird die DLL geladen und in der Variable GetInstance die Adresse der DLL funktion GetInstance gespeichert. dann kommt noch wenn man auf einen Knopf drück
rechner := GetInstance; ergebnis := rechner.Rechenart1(5,6);rechner is vom Typ pTRechner. Soblad das aufgerufen wird gibs ne Access violation