Solved

Dynamic package loading

Posted on 1998-10-07
6
793 Views
Last Modified: 2009-12-16
Is there a way to get hold of a function in a package the same way as with .dll's (GetProcAddress). The thing is that I'd like to have a base class say TMyBase. In the application I'd like to load components dynamically so I dont know the name of the main class in the components. The component's main class inherits from TMyBase and implements a function <function GetMainClass : TMyBase>. When the application starts loading components I'd like it to work like this

     TGetMainClass = function(....) : TMyBaseClass;
     ....

> OnCreate-------
  var
      aGetMainClass : TGetMainClass;
  begin
     for i:=0 to myPackageList.count-1 do
     begin
          myPackageList[i].itsHandle := LoadPackage(myPackageList[i].itsName);
          @aGetMainClass := GetProcAddress(myPackageList[i].itsHandle, 'GetMainClass');
          myPackageList[i].itsMainClass := aGetMainClass(..)
     end;

This way I can read the settings in the registry file to obtain the components installed and easely install a new component without recompiling the application.

The problem I have is that @aGetMAinClass returns nil?  
0
Comment
Question by:peed112097
  • 3
  • 2
6 Comments
 
LVL 2

Accepted Solution

by:
Hagen040798 earned 500 total points
Comment Utility
Hi

Your write this code in the External-Package

inialization
  RegisterClasses([TMyClass]);
finalization
  UnregisterClasses([TMyClass]);
end.

Then Your load the external-Package with LoadPackage, the initialization Section from all units in the Packages will called and so register the TMyClass. Now You can acces with GetClass('TMyClass') = TMyClass also GetClass('TMyClass').Create ..... and so on.

Hagen.
0
 

Author Comment

by:peed112097
Comment Utility
OK, but where do I put the
inialization , finalization code? Is it in the package file?
0
 

Author Comment

by:peed112097
Comment Utility
I also can't figure out how to gegister the class. Do I have to typecast the class name to TPersistantClass?
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 2

Expert Comment

by:Hagen040798
Comment Utility
Hi peed, here a short Example with separate Registration.

unit RegClass;
{this unit handled the Registration from the Classes.
 this unit must pack in a package to acces from the external Modules
 to Examples this unit in Main.dpl}
interface

uses Classes;

{register Classes}
procedure RegisterModuleClasses(const Classes: Array of TClass);
{unregister Classes}
procedure UnregisterModuleClasses(const Classes: Array of TClass);
{get back a registered Class with the specific ClassName}
function GetModuleClass(const ClassName: String): TClass;
{get back the List of registered Classes}
function ModuleClassList: TStrings;

implementation

const
  FList: TStringList = nil;

function ModuleClassList: TStrings;
begin
  if FList = nil then
  begin
    FList := TStringList.Create;
    FList.Sorted := True;
    FList.Duplicates := dupIgnore;
  end;
  Result := FList;
end;

procedure RegisterModuleClasses(const Classes: Array of TClass);
var
  I: Integer;
begin
  for I := Low(Classes) to High(Classes) do
    if Classes[I] <> nil then ModuleClassList.AddObject(Classes[I].ClassName, Classes[I]);
end;

procedure UnregisterModuleClasses(const Classes: Array of TClass);
var
  I,J: Integer;
begin
  for I := Low(Classes) to High(Classes) do
    if Classes[I] <> nil then
    begin
      J := ModuleClassList.IndexOf(Classes[I]);
      if J >= 0 then ModuleClassList.Delete(J);
    end;
end;

function GetModuleClass(const ClassName: String): TClass;
begin
  I := ModuleClassList.IndexOf(ClassName);
  if I >= 0 then Result := ModuleClassList.Objects[I]
    else Result := nil;
end;

initialization
finalization
  FList.Free;
  FList := nil;
end.

{-------------------}
unit MyTestModules;

{this Unit pack in a external Package or Library, add the packgage with included RegClass,
 and compile with the Package-option
 to Example this unit in MyModule.dpl and add Main (Main.dpl) in Projectoptins\Packages}

interface

uses Classes, ....;

type
  TMyClass = class(from TXYZObject)
    procedure XYZ;
  end;

implementation

uses RegClass;

procedure TMyClass.XYZ;
begin
{....}
end;

initialization
  RegisterModuleClasses([TMyClass]);
finalization
  UnRegisterModuleClasses([TMyClass]);
end.

{-----------------------------}
unit MainTest;

{This unit is the Application-unit}

interface

uses RegClass;

type
  TmyForm = class(TForm)
    function LoadAndCreateMyClass: TObject;
  end;

implementation

function TMyForm.LoadAndCreateMyClass: TObject;
var
  Module: hModule;
  C: TClass;
begin
  Result := nil;
  Module := LoadPackage('MyModule.dpl');
{when load a package or library then was called all initialization-Section from the
 contained Units, in this Sections you must call RegisterModuleClasses and after
 the loading you can access to the registered classes with GetModuleClass per Name, yust here}
  C := GetModuleClass('TMyClass');
  if C <> nil then Result := C.Create {create the Object}
    else UnloadPackage(Module); {unload the Package, Class was not registered}
end;

{I hope that help Your.
 When you has Questions then post me Your E-Mail-address and i make a Example for you or i send
 Your my Project from my Firma. This is very better and complex.
 The best Way is you define a Basisclass with defined interface-function's, in my Firma we
 use a Descend from TForm with a function to Exchange Datas from the Form, all ModuleForms
 used the BaseFormClass. The Implementaion from this BaseForm is placed in RegClass.
 We have also Formular's in DLL's and loading this dynamicly at Runtime and Unloading when the
 Form is destroyed.

 Sorry for my english. Hagen }

end.




0
 
LVL 2

Expert Comment

by:Hagen040798
Comment Utility
Hi peed

The initialization and finalization Sections placed in units at last not in the Package-Project-File (in *.pas not in *.dpr). This sections initialize the Unit and finalize the Units. A Package-DLL export two function's "Initialize" and "Finalize" this calls all initialization and finalization -Section's all units contained in a Package, in my Firma we use not Packages but Library's this is better.
When your not will use RegisterClasses from Classes you can write functions the Register other Classes.
to Example:

type
  TMyClass = class of TMyObject;
  TMyObject = class(TObject)
  end;


function RegisterMyClass(const Classes: array of TMyClass);


Hagen.
0
 

Expert Comment

by:ekoindri
Comment Utility
not work in delphi 2007 + vista
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now