We are starting to use Hydra in our projects and a simple question have arisen: what we need in order to share an object (a connection, a grid or a simple Object) between host (an EXE) and a DLL written with Hydra in order to get a small EXE and several plugins in a DLL format (both in Delphi).
We have successfully created a small project which shares (send and receive) an object between them but it seems that, in order to make it work in another computer (without Delphi installed) we need to send several BPLs.
Is that correct? Should I have to package all third party components and send them along in BPLs in order to use them that way?
for sharing Delphi objects in Delphi you should build host and plugin with runtime packages.
You should use packages only for components what you want to share between host and plugin.
for example, if you have visual plugin that uses DevEx controls you may avoid putting it to shared runtime package because DevEx controls are used only by plugin.
Is there a difference between a Component and an Object? When should I have to include a component in a runtime package?
For instance, if I define a simple object in host and want to share it with plugin, should I have to create a package just to share it ?
if you are passing any delphi object (class, component) between host and plugin you should put it into shared runtime package otherwise it won’t be read correctly on other side.
I’ve tested with an object (below: TSharedObjList) and it worked without packaging it in a runtime package. Is there any rule that controls what we could share or not?
For us, it a little bit of annoyance have to put every object we define to share between them in a BPL.
TSharedObj = class(TObject) private FID: Integer; FValor: Extended; FCampoTesteSubNivel: String; public property ID: Integer read FID write FID; property Valor: Extended read FValor write FValor; property CampoTesteSubNivel: String read FCampoTesteSubNivel write FCampoTesteSubNivel; end; TSharedObjList = class(TObjectList<TSharedObj>) private public end;
are you passing it between plugin and host?
at least this case doesn’t work with standard TStrings …
Yes, I am passing it between them (host and plugin). The two projects, host and plugin, are compiled with the definition of the object and we are successfully passing it between them without errors.
if you’re not using packages, then you’re just getting lucky. for example, casting them or checking their type might fail unexpectedly, because their types (and type hirarchy) are technically different (if identical).
I don’t know why as I am sharing a unit (with the definition of the object) between Host and Plugin. Why their types would be different?
Because both get compiled separate, and against the separate
TObject (and other) ancestor classes of the RTL/VCL that are duped in each .dll. So the types are identical binary wise (so no error when you use them interchangeably, because their memory layout “happens” to match , but if you ask “whats this type” you get a pointer to two unque type definitions for each, one in dll1 and one in dll2. If you compare the two (say
if x is MyClass), you’d get a result that they aren’t.
if that makes sense.
That makes sense but I can’t think of an example in which their memory layout wouldn’t fit if both would be compiled in the same environment (same Delphi, libraries, etc).
Anyway, I would make two BPLs: one for third party components and other with my shared objects.
right. thats why you got away with it. But ting will fail if you’d ever do something such as
var x := theMsComponentReceivedFromPlugin as TMyComponent.
Alright, but if I just use it (consuming their properties), is there any example?
I know that I am being a little picky here but I just want to understand and not just use it as recommended (which, BTW, I will).
Just another small question: if I have the unit shared between both projects, in order to use the BPL (the runtime package) I have just to tell Delphi to compile with those runtime packages?
Hard to say. it also depends on what the component’s code does, inside. Basically: if it works, good. just dont be surprised if you get “unexpected” ‘cannot cast A to A’ errors
as Marc said, you may get this error
‘Cannot assign a XXX to a XXX’
in this case, this type (XXX) should be put to shared runtime package.
OK, I understood that for shared objects, eg objects that we need to pass between host and plugin, we have to put them in a single BPL.
But, is it required for objects that we just use in a plugin too? For instance, if we use DevEx grid in a plugin, do I have to create a BPL with it in order to use this plugin? or I could compile the plugin normally (without runtime packages)?
That should be fine.