Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically loaded BPL's sharing code / passing objects

Tags:

delphi

bpl

I was toying around with the idea of using dynamically loading BPL's and passing object instances from the main app to a method in a BPL. This poses a problem units between used by the application and by the BPL.

I wrote a small little prototype which did this and was curious how Delphi internally manages differences between classes defined in the app vs. the BPL.

For example, say a basic Widget class like:

TmyWidget = class
private
  fId:Integer;
  fDescription:String;
public
  procedure DoSomething1();
end;

Now the app and the BPL are built using the unit containing TmyWidget class. Later, something changes in TMyWidget and the app is rebuilt, but the BPL is not (or vice-versa.) I added another method DoSomething2() and created an instance of TmyWidget in the app and passed it to the BPL for processing and in the basic example, it worked. But it's obviously fraught with potential problems.

If another dynamically loaded BPL also uses TmyWidget then things get even more interesting. It seems to work, but it definitely doesn't feel ideal.

The main question is - how does one typically pass objects to and from the main application and DLLs or BPLs? I've never attempted it before and likely for a good reason, but I've got this idea that lends itself to this approach...

I'd imagine that the best approach is to serialize the object and pass those bytes over and deserialize it in the DLL/BPL with this process being mindful of potential version differences between the host and the dynamically loaded module but I was hoping the new SimpleSharedMem option might bring this new functionality without the overhead of serialization, but it seems to be not very useful unless you are strict in keeping the app and dll rebuilt on any shared code changes...but in this prototype, the app would stay fairly constant and the dynamically loaded modules would be changing frequently with functionality being added to TmyWidget. (The server app serves as the factory for building TmyWidget's based on client requests and the app would pass instances to the various modules for processing.)

like image 670
Darian Miller Avatar asked Dec 03 '22 09:12

Darian Miller


1 Answers

...was curious how Delphi internally manages differences between classes defined in the app vs. the BPL

Delphi manages this by not allowing it. You can't have a unit with the same name in multiple packages at the same time: if you do, you get an error message saying something similar to Package XYZ already contains ABC (haven't seen that in a while...). Since the type name includes the unit name, you can't have the same type in two different packages. Unless it's a Interface defined by it's GUID, but that's a different story.

... how does one typically pass objects to and from the main application and DLLs or BPLs?

You don't pass objects to DLL, that's not a good idea. When you need to pass objects to a BPL, make sure the base class for that BPL is defined into an 3rd BPL.

Example. Polymorphic behavior for your TmyWidget is probably defined using some virtual methods. Make sure you have a TmyWidgetBase class that defines all of those virtual methods, derive all your TmyWidget's from that base class and pass around objects with the type TmyWidgetBase. Make sure the TmyWidgetBase class is in it's own Package.

When I attempted doing this I ended up with an tiny "bootstrap" exe and lot's of BPL's. Essentially all the logic was in BPL's, to facilitate passing objects around.

like image 137
Cosmin Prund Avatar answered Jan 28 '23 04:01

Cosmin Prund