Board index » cppbuilder » Advanced: using a D5 written DLL in C++Builder4
Peter Feenstra
![]() CBuilder Developer |
Advanced: using a D5 written DLL in C++Builder42003-08-01 03:32:34 PM cppbuilder2 We have written a 'V43lib.dll' in Delhi5 we wish to use in C++Builder 4. If we try to "follow the rules" we get tons off errors, but if we do the following it runs (almost) OK. With Implib we create a V43lib.lib file for this dll. In a new project under C++Builder4 we use this lib. Next we add a header file with the translation in C++ (TNsNavigation) of the Delphi wrapper class decribed below. And the declaration of the imported functions: extern "C" { TNsNavigation* __declspec(dllimport) __stdcall InitNavigation(TComponent *AOwner); void __declspec(dllimport) __stdcall FreeNavigation(); } In the private section of TForm1 (in C++Builder) we have written: private: // User declarations TNsNavigation *Paco; Now comes the serious part: if we do this in C++Builder: void __fastcall TForm1::FormCreate(TObject *Sender) { Paco = InitNavigation(this); if ( Paco != NULL ) { Paco->OnMainObsDownLoadProgres = FUpdateDownLoadMemo; Paco->OnRouteUpdate = FUpdateRouteInfo; } ... } At the start of the Application we get first an empty dialog as wide as the screen with an OK button. If you click OK you get a small dialog with a few 'chaos' characters and an OK button. If you click OK next you get access errors. But if we do this: void __fastcall TForm1::FormCreate(TObject *Sender) { LoadLibrary("V43lib.lib"); Paco = InitNavigation(this); if ( Paco != NULL ) { Paco->OnMainObsDownLoadProgres = FUpdateDownLoadMemo; Paco->OnRouteUpdate = FUpdateRouteInfo; } ... } At the start of the application we first get a message that 'V43Lib.lib' is not a valid windows image and if we click ok the whole thing runs smoothly without problems. The first message is correct of course because 'V43Lib.lib' is not a dll but the result of Implib. The question is how to get rid of this message. We expected that in Delphi5 we should have written: function InitNavigation(AOwner:TComponent):TNsNavigation; stdcall; {$IFNDEF V43Lib} external 'V43lib.dll' {$ENDIF} procedure FreeNavigation(); stdcall; {$IFNDEF V43Lib} external 'V43lib.dll' {$ENDIF} But this results in the same errors as decribed above with the dialogs and access errors. In Delphi we have the following situation: in the interface section of a unit we have: TNavigatie = class(TComponent) private FOnRouteUpdate :TNotifyEvent; FRouteUpdateEventEnable :boolean; FOnObstructionsFound :TNotifyEvent; FObstructionsFoundEventEnable:boolean; FOnCalculationFail :TNotifyEvent; ... public Captions : TCaptions; MemoStrings : TMemoStrings; RouteTrack : TRouteTrack; ... // Main functions/procedures constructor Create(AOwner:TComponent); override; destructor Destroy; override; function MainObstructionsFileDate():string; function MainObstructionsCreationDate():string; function MainDownLoadObstructions():boolean; ... published // Main Properties property OnMainObsDownLoadProgres :TFtpProgresEvent read FOnMainObsDownLoadProgres write FOnMainObsDownLoadProgres; property MainSelectedRoute :integer read FSelectedRoute; // Route Properties property OnRouteUpdate :TNotifyEvent read FOnRouteUpdate write FOnRouteUpdate; property OnRouteObstructionsFound :TNotifyEvent read FOnObstructionsFound write FOnObstructionsFound; ... end; To export this class we've written a wrapper in wich we wrap the properties and methods we want to export: {$Define V43Lib} TNsNavigation = class(TObject) private //MAIN FOnMainObsDownLoadProgres:TFtpProgresEvent; //SHIPS FOnShipsListUpdate :TNotifyEvent; FOnShipsShipUpdate :TNotifyEvent; //ROUTE FOnRouteUpdate :TNotifyEvent; ... public {$IFDEF V43Lib} Constructor Create(); {$ENDIF} //MAIN function MainGetCopyright: string; virtual; stdcall; {$IFNDEF V43Lib} abstract; {$ENDIF} Function MainDownLoadObstructions():Boolean; virtual; stdcall; {$IFNDEF V43Lib} abstract; {$ENDIF} procedure MainApplyDownloadedObstructions(); virtual; stdcall; {$IFNDEF V43Lib} abstract; {$ENDIF} procedure MainCancelDownloadedObstructions(); virtual; stdcall; {$IFNDEF V43Lib} abstract; {$ENDIF} ... published //MAIN property OnMainObsDownLoadProgres :TFtpProgresEvent read FOnMainObsDownLoadProgres write FOnMainObsDownLoadProgres; //SHIPS property OnShipsListUpdate :TNotifyEvent read FOnShipsListUpdate write FOnShipsListUpdate; end; function InitNavigation(AOwner:TComponent):TNsNavigation; {$IFNDEF V43Lib} external 'V43lib.dll' {$ENDIF} procedure FreeNavigation(); {$IFNDEF V43Lib} external 'V43lib.dll' {$ENDIF} //according to the rules this should be: {function InitNavigation(AOwner:TComponent):TNsNavigation; stdcall; {$IFNDEF V43Lib} external 'V43lib.dll' {$ENDIF}} {procedure FreeNavigation(); stdcall; {$IFNDEF V43Lib} external 'V43lib.dll' {$ENDIF} } // now we declare 2 vars Var GNavigatie : TNavigatie; GNsNavigation : TNsNavigation; // In the implementation section we do this: implementation // Internal constructor -------------------------------------------------------- constructor TNsNavigation.Create(); begin inherited Create(); // Definitions of the event properties: GNavigatie.OnMainObsDownLoadProgres := FSendMainObsDownLoadProgresEvent; GNavigatie.OnRouteUpdate := FSendRouteUpdateEvent; ... end; ... function TNsNavigation.MainGetCopyright: string; Begin Result:=CopyRight end; Function TNsNavigation.MainDownLoadObstructions():Boolean; Begin Result:=GNavigatie.MainDownLoadObstructions(); end; procedure TNsNavigation.MainApplyDownloadedObstructions(); Begin GNavigatie.MainApplyDownloadedObstructions(); end; ... // Finally we do this: // External constructor -------------------------------------------------------- function InitNavigation(AOwner:TComponent):TNsNavigation; begin ... if Assigned(GNavigatie) then GNsNavigation := nil else begin GNavigatie := TNavigatie.Create(AOwner); GNsNavigation := TNsNavigation.Create(); end; result := GNsNavigation end; // External destructor -------------------------------------------------------- procedure FreeNavigation(); begin ... if Assigned(GNavigatie) then begin GNavigatie.Free; GNsNavigation.Free; end; end; // In the library unit we do this uses ShareMem, SysUtils, Classes, unitAsDecribedAvove, ... ; {$R *.RES} Exports InitNavigation, FreeNavigation; begin end. I hope someone can help us out of this problem. Thanks in advance, Peter Feenstra |