External modules implementation
Asked Answered
M

2

5

What is the best way to implement an external module system for a DELPHI application?

What I need is very basic really:

  • The main APP detects if a module is present and loads it(Run time)
  • Modules can store form
  • Modules can store DataModules
  • Modules can Store code

I need the use the store forms inside other forms, and only as a standAlone

I use something like this

        if Assigned(pNewClass) then begin
            Application.CreateForm(pNewClass, _lFrm);
            _lFrm.Hide;
            _lFrm.BorderStyle := bsNone;
            _lFrm.Parent := pBasePNL //(TPanel);
            _lFrm.Align := alClient;
        end;

So I create a TForm, but place it inside a TPanel.

As for DataModules I usally store ImageLists so the ideia is to change the app ICOs just bit changing the external module.

So what is the best way to achieve this?

Looked at runtime BPLs but don’t seem to understand how to do it. Thanks.

UPDATE : .....................................

After reading some related question and answers i think I found my answer and solution.

http://edn.embarcadero.com/article/27178

The article is old stuff but amazingly simple.

Well the logic is there I just don’t seem to get it to Show the forms 

I am just testing example 2

It loads the BPL, but doesn’t get the Form:

AClass := GetClass('TForm2');

Always retrievex ‘nil’

But the BPL as it registered:

RegisterClass(TForm2);

Can anyone help with this one.

Morningglory answered 20/8, 2011 at 11:27 Comment(4)
You might find more information if you look for pluginsProvo
This really is a duplicate, just look at the list of related questions to the rightRuffner
Just did, thanks. Just found my solution there.Morningglory
You don't need to use GetClass. See my answer for a demo.Christman
C
3

I made you a demo, it's so easy to get started! However... Started is not finished.

Every time I started using plugins, I later regretted it. However, as you say, you want a binary plugin system. So BPLs are the correct solution. David suggests using interfaces (with plain DLLs instead of the full runtime package BPL) and this would solve some of the commonly encountered BPL-instability problems due to not versioning your classes, and thus your Application-and-package-binary-compatibility dependencies, properly. If you do not need to share memory and do not need to use borlandmm.dll (shared memory management) then a straight DLL with interfaces will work fine.

If you can do everything you need to do with just scripting, and make your plugin system with just scripts, then do it that way. If you can get away with DLLs, interfaces, and no memory sharing, then use plain DLLs. If you must share Memory and class types, then yes, use BPLs.

Beware that using BPLs (Runtime Packages) comes with a lot of side effects you might not have been expecting. The largest BPL-based applications I have worked on have been more of a mess, and less stable, than any monolithic apps I have worked on. It seems that it is only possible to pine for packages until you try them, and then I find, I pine for monoliths again.

If you use BPL packages correctly, and you version your plugins properly, everything is fine. BPLs are great. But in the real world, it seems that sane versioning and ABI compatibility and interoperability, and stability are at a premium.

Update: I made you a demo it's here (plugin_r2.zip). It was done in Delphi XE, but if you are using an older version of delphi, you just delete the .dproj files and open the .dpr file for the main app, and the .dpk for the package.

Christman answered 1/9, 2011 at 9:23 Comment(5)
What i need is to store forms, datamodules, and resources inside a BPL. The goal is to create extra modules for the main APP, that I give the client or not. Every time I build the main, I will rebuild the modules(BPLs). DELPHI version is not a problem I work in 2007 and plan to keep it for some time its to expansive. What not working now is GetClass.Morningglory
I made you a demo, see the last link the answer above! If you aren't using delphi XE, then delete the DPROJ file, and open the .dpr file, and it should still work.Christman
Thanks for the DEMO, but "mainFormMainUnit1.pas" is missing.Morningglory
I fixed the zip file and uploaded it again. Download plugin_r2.zip from the same link above.Christman
In a real implementation you might want to have it register multiple forms, perhaps you might want to let the main app decide which ones it wants to instantiate, by class name. You also might want to let the plugins access the main application's data and so on. So obviously it can get a lot more complex.Christman
L
4

Packages are an easy solution but they have one huge drawback. Using packages forces plugin authors to use not only Delphi, but the same version of the compiler as you do.

I personally would prefer to expose the functionality of the app through a number of interfaces. This allows accessibility from languages other than Delphi.

Typically the plugin would be implemented in a DLL and would export a function that the app would call to pass in the root interface representing the app. The plugin would then call methods of that interface thus establishing two-way interaction.

Lobel answered 20/8, 2011 at 12:2 Comment(2)
If he wants to return Datamodules and Delphi forms as the question states, this advise is not that useful. Since the returned forms will be Delphi and version dependent anywaySectarian
But it is a good idea to warn people away from shark infested waters. Thus, +1 for David.Christman
C
3

I made you a demo, it's so easy to get started! However... Started is not finished.

Every time I started using plugins, I later regretted it. However, as you say, you want a binary plugin system. So BPLs are the correct solution. David suggests using interfaces (with plain DLLs instead of the full runtime package BPL) and this would solve some of the commonly encountered BPL-instability problems due to not versioning your classes, and thus your Application-and-package-binary-compatibility dependencies, properly. If you do not need to share memory and do not need to use borlandmm.dll (shared memory management) then a straight DLL with interfaces will work fine.

If you can do everything you need to do with just scripting, and make your plugin system with just scripts, then do it that way. If you can get away with DLLs, interfaces, and no memory sharing, then use plain DLLs. If you must share Memory and class types, then yes, use BPLs.

Beware that using BPLs (Runtime Packages) comes with a lot of side effects you might not have been expecting. The largest BPL-based applications I have worked on have been more of a mess, and less stable, than any monolithic apps I have worked on. It seems that it is only possible to pine for packages until you try them, and then I find, I pine for monoliths again.

If you use BPL packages correctly, and you version your plugins properly, everything is fine. BPLs are great. But in the real world, it seems that sane versioning and ABI compatibility and interoperability, and stability are at a premium.

Update: I made you a demo it's here (plugin_r2.zip). It was done in Delphi XE, but if you are using an older version of delphi, you just delete the .dproj files and open the .dpr file for the main app, and the .dpk for the package.

Christman answered 1/9, 2011 at 9:23 Comment(5)
What i need is to store forms, datamodules, and resources inside a BPL. The goal is to create extra modules for the main APP, that I give the client or not. Every time I build the main, I will rebuild the modules(BPLs). DELPHI version is not a problem I work in 2007 and plan to keep it for some time its to expansive. What not working now is GetClass.Morningglory
I made you a demo, see the last link the answer above! If you aren't using delphi XE, then delete the DPROJ file, and open the .dpr file, and it should still work.Christman
Thanks for the DEMO, but "mainFormMainUnit1.pas" is missing.Morningglory
I fixed the zip file and uploaded it again. Download plugin_r2.zip from the same link above.Christman
In a real implementation you might want to have it register multiple forms, perhaps you might want to let the main app decide which ones it wants to instantiate, by class name. You also might want to let the plugins access the main application's data and so on. So obviously it can get a lot more complex.Christman

© 2022 - 2024 — McMap. All rights reserved.