Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Dynamic package loading

Posted on 1998-10-07
6
Medium Priority
?
806 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
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!

 
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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

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…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
This lesson discusses how to use a Mainform + Subforms in Microsoft Access to find and enter data for payments on orders. The sample data comes from a custom shop that builds and sells movable storage structures that are delivered to your property. …
Suggested Courses

604 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