Jump to content
Sign in to follow this  
krayna

Share FireDac Tables over DLL boundries

Recommended Posts

Hello everyone, I am in the process of converting an old project from Bde to Firedac. Basically it's relatively easy, but now I'm at a point where I'm a bit desperate. With the Bde, TDatabase and TTable/TQuery components, I had set up a central connection in my main program and opened all the necessary TTable tables. Now DLLs of the program (dynamically loaded with LoadLibrary) could call a function in the central location (export method) and, for example, fetch a TTable object corresponding to a specific table. Regardless of whether the design is good or bad, it worked without any problems. We used "ShareMem" in the main application and all the DLLs. I then had access to the tables of the main program in the DLL and could, for example, call FindKey to jump to a specific position in the DB.
With Firedac I left everything as it was, only instead of TDatabase I used TFDConnection and accordingly TFDTable etc. The code is definitely correct, I can connect and display the data in the Dbgrid. FindKey from the main program also works. Nevertheless, I always get false with FindKey from the DLL after I have fetched the TFDTable. Does anyone have any experience with this? Could it be that the connection does not arrive correctly in the DLL when I get the TFDTable object? On the other hand, something like fdtable.fieldbyname(...) works without problems from the DLL.

So I don't understand why FindKey doesn't work. It is also the same TFDTable object that I get back from my main application, indexfieldnames is also correct, table and connection are open and everything. Nevertheless it does not work. Would be grateful for a hint, especially since it works with TTable. I hope I was able to explain the problem. FindKey was just an example, I´m not sure, if other methods called in the dll work properly either.

The Idea behind this concept is that we have a central place and all DLLs have access to the main tables and can change the cursor position of the table or can be updated when another DLL changes the position of a table, because they all use the same tables from the main application. Is there a better concept for this in FireDac with DLLs? Or do I need to create methods in my main application for Table updates or methods like "FindKey" which can be called from the DLLs? That would be a huge refactoring and I want to avoid this!

Thanks a lot!

Share this post


Link to post

Using Sharemem may give you a common memory manager for host app and dlls, but you still have separate code "instances" for all RTL and VCL stuff you use on both sides, which includes any global variables the units in question may use internally, the Application and Screen objects etc.  If this worked in the past you have simply been lucky :classic_dry:, but your luck appearendly ran out when you switched to the more complex FireDac framework.

 

The only safe way to share object references between modules is to use packages instead of DLLs. Unfortunately, packages are all or nothing, you have to build host program and your own packages (which replace the DLLs you now use) with packages and deploy all the required run-time packages of the RTL, VCL, and whatever else (e.g. 3rd party stuff) to the user's PCs. Not fun. And if you load packages dynamically better not try to unload them in code as well, that has been a source of hard to track errors due to premature RTL etc. unit finalization in the past (may have been fixed but is hard to verify).

 

If you want to stick with DLLs you need a different design that shares interface references instead of object references between the modules. Host and DLLs would use a common unit with the interface declarations; all exported functions would use interface references instead of object references. For the classes you now share you would have to write a layer of TInterfacedObject-derived wrappers that implement the interfaces that allow you to safely call methods and access properties od the wrapped objects.

Share this post


Link to post

Thank you very much for the detailed answer and for the explanation!

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×