| Dynamic World of Packages | |
|
Calling routines in Packages that are dynamically loaded isn't a lot of fun. Several routines and API calls need to be used in order to get the AboutBoxForm displayed.
0. We need a button (Button1) on a form (Form1) that represents our application:
1. The LoadPackage function loads a specified package. In our case we expect the TestPack.bpl to be stores in the applications directory. The function returns the hModule value - stored inside a phm (as Package hModule) variable. Note: ExecF is declared to be a variable of a procedural type. Procedural types allow you to treat procedures and functions as values that can be assigned to variables or passed to other procedures and functions.
I'll give you the explanation, then the code:
2. If the Package is loaded (phm <> 0) we move on:
3. The GetProcAddress function retrieves the address of the specified exported dynamic-link library (DLL or BPL) function. The first parameter to this function is a handle to the BPL module that contains the function (that is the phm value). The Second parameter contains the function name (Execute).
4. If the call to GetProcAddress succeeds we can use our function.
5. The call to ExecF is made (that is the call to Execute) and if the user has picked the first radio button the 'True' is returned; 'False' otherwise.
6. Finally we unload the Package and move on....
procedure TForm1.Button1Click(Sender: TObject);
var
phm: HModule;
ExecF: function(const p1,p2,p3: string): boolean;
sDisplayText, sYes, sNo : string;
begin
sDisplayText:='Hi, I''m the Delphi Form
called from a dynamically
loaded runtime Package!';
sYes := 'This is great';
sNo := 'This sucks!';
{suppose package is in application's directory}
phm:=LoadPackage(ExtractFilePath(ParamStr(0))
+ 'TestPack.bpl');
if phm <> 0 then
try
@ExecF:=GetProcAddress(phm,'Execute');
if Assigned(ExecF) then begin
if ExecF(sDisplaytext, sYes, sNo) = True then
ShowMessage('True!')
else
ShowMessage('False!');
end else begin
ShowMessage ('Execute routine not found!');
end{if assigned}
finally
UnloadPackage(phm);
end {try/finally}
else {if hpm<>0}
ShowMessage ('Package not found');
end;

That's it
This concludes our task. We have seen how to store a (custom) Delphi form inside a run-time Package and how to call that form at run time by dynamically loading a Package. Even more: we saw a great way of sending some data to the form, creating and displaying a form a finally retrieving some data from it.
Note that there is a sample code with this article that can be downloaded.
What stays unanswered here is how to place our own component inside a Package and use one instance of the component class with the dynamically loaded Packages. I'll leave this for some future article.
First page > Static linking or dynamic loading? > Page 1, 2, 3

