?
Solved

Dynamic package loading

Posted on 1998-10-07
6
Medium Priority
?
803 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 2000 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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

Independent Software Vendors: 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!

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
Suggested Courses
Course of the Month14 days, 11 hours left to enroll

771 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