Solved

Dynamic package loading

Posted on 1998-10-07
6
800 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
6 Comments
 
LVL 2

Accepted Solution

by:
Hagen040798 earned 500 total points
ID: 1342134
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
ID: 1342135
OK, but where do I put the
inialization , finalization code? Is it in the package file?
0
 

Author Comment

by:peed112097
ID: 1342136
I also can't figure out how to gegister the class. Do I have to typecast the class name to TPersistantClass?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 2

Expert Comment

by:Hagen040798
ID: 1342137
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
ID: 1342138
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
ID: 24902937
not work in delphi 2007 + vista
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi Spellcheck in Webbrowser 1 52
Delphi application Soap connection 5 135
Dev Express grid collapse 2 48
How to make Sign in, using Clientdataset? 1 33
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

730 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