FabDev 8 Posted January 14, 2020 Hello, I have tested CData components (Free with Delphi Enterprise version). It's is a very interesting components set : All API, Webservice become "Table and queries". But I have a problem if you integrate the component to open Excel file your executable is increased by 14 MB ! I need to add 5 or 10 CData components (like Excel, Excel Online, FTP etc.). After this the executable size do more than 100 MB. With runtime library it's the same problem. The customers of my software don't need to use all components each time. So I would like to dynamically load the BPL file using LoadPackage when needed. To do this I use I try to use LoadPackage like this : procedure TForm10.Button1Click(Sender: TObject); var PackageModule: HModule; AClass: TPersistentClass; begin PackageModule := LoadPackage('CData.Excel.D26.bpl'); if PackageModule <> 0 then begin AClass := GetClass('TFDPhysCDataExcelDriverLink');// no effect with ('TFDPhysCDataExcelDriver'); if AClass <> nil then begin with TComponentClass(AClass).Create(Application) as TFDPhysCDataExcelDriverLink do begin create(self); // FDPhysManager().RegisterDriverClass(TFDPhysCDataExcelDriverLink); // FDConnection1.Name := 'SQLTest'; FDPhysManager().RegisterRDBMSKind(cDBMSKindCData, S_CData_DriverID); // FDPhysManager().RegisterDriverClass(TFDPhysCDataExcelDriverLink); FDConnection1.DriverName := 'CData.Excel'; with FDConnection1.Params as TFDConnectionDefParamsClass do begin add('File=C:\MyExcelWorkbooks\SampleWorkbook.xlsx'); end; FDQuery1.SQL.clear; FDQuery1.SQL.add('SELECT * FROM Sheet WHERE FirstName = ''Bob'''); FDQuery1.ExecSQL; Free; end; end else showmessage('error'); UnloadPackage(PackageModule); end; end; Initialization RegisterClass(TFDPhysCDataExcelDriverLink); // RegisterClass(TFDPhysCDataExcelDriver); end. But at line "FDQuery1.ExecSQL;" I get this error "[Firedac][Phys]-300 Driver [CData.Excel] is not registered. Correct The ID of the driver or define the virtual drivers [CDATA.Excel] in FDDrivers.ini". Certainly because a line like this is missing : FDPhysManager().RegisterDriverClass(TFDPhysCDataExcelDriver); But I don't know how to dynamically Register a driver class to Firedac ! Any idea ? (Full source in attachment) DynamicBPLExcel.zip Share this post Link to post
David Schwartz 426 Posted January 15, 2020 (edited) You said: if AClass <> nil then begin with TComponentClass(AClass).Create(Application) as TFDPhysCDataExcelDriverLink do begin create(self); but I'm curious why you're calling create(self) when the context is already operating on a newly created instance? You seem to be creating an instance of something, then casting it into a (probably much larger) object and then recreating it. something := TFDPhysCDataExcelDriverLink( TComponentClass(AClass).Create(Application) ).Create(self); This does not look kosher to me. Edited January 15, 2020 by David Schwartz Share this post Link to post
FabDev 8 Posted January 15, 2020 (edited) 10 hours ago, David Schwartz said: something := TFDPhysCDataExcelDriverLink( TComponentClass(AClass).Create(Application) ).Create(self); Yes it's better to avoid ambiguity of "Self" but in this case by default Delphi seems to consider (Self=Form10). But I think that it miss something like (done in initialization of unit FireDAC.Phys.CDataExcel.pas) : FDPhysManager().RegisterDriverClass(TFDPhysCDataExcelDriver); But : AClass2 := GetClass('TFDPhysCDataExcelDriver'); Return nil... Edited January 15, 2020 by FabDev Share this post Link to post