Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations MikeeOK on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Interface as library entry point

Status
Not open for further replies.

rcloutie

Programmer
May 26, 2005
164
CA
Hi there,

I've defined an interface in a unit which is implemented in all of my forms. Now that the project becomes too large, I thought creating separate DLLs which will includes each module's specific forms.

Menu.exe
- Module1.dll {Form1-1; Form1-2; Form1-3}
- Module2.dll {Form2-1; Form2-2; Form2-3}
- Module3.dll {Form3-1; Form3-2; Form3-3}

Here's my problem: I would like to have my interface as the libraries entry points (a bridge between my main EXE and separate DLLs). Do I need to create a new library for my interface (tlb or dll?) for the interface type to be known?

Any idea how to do it or even better sample source code?

Thanks a lot in advance,
 
If you want to access routines defined in one DLL via an interface than maybe the following steps will help you.

Step 1:
Define an interface.

Code:
unit MyInterfaceUnit;

interface

type 
    IMyInterface=interface
    //[press Ctrl+Shift+G to generate interface unique ID]
      procedure MyProcedure();        stdcall;
      function  MyFunction():Boolean; stdcall;
    end;
implementation


Step 2
Define a unit where you implement this interface.
Code:
unit MyInterfaceImplementation;

interface

uses
   MyInterfaceUnit;

type 
    TMyInterfaceClass=class(TInterfacedObject,IMyInterface)
    public
      procedure MyProcedure();        virtual; stdcall;
      function  MyFunction():Boolean; virtual; stdcall;
    end;


implementation

procedure TMyInterfaceClass.MyProcedure();
begin
    //your code 
end;

procedure TMyInterfaceClass.MyFunction():Boolean;
begin
    //your code
end;


//Define a function that will create your object 
//as you will see below this function is the only thing 
//you will need to export
function CreateMyObject():IMyInterface;
begin
    result:=TMyInterfaceClass.Create();
end;

Step 3
You will need to define and export one function that will create your object and return a reference to your interface. (In the above "CreateMyObject" serves as that function).


Step 4.
Create a DLL project and add MyInterfaceImplementation unit and compile.



Finally
To use DLLs functionality you simply need to refer to one function of the DLL which is the only one thats exported (That is CreateMyObject in the above example).

...e.g.
Code:
var
  my:IMyInterface;
...
LibHandle:=LoadLibrary('YourLib.dll');
my:=GetProcAddress(LibHandle,'CreateAddOn');




something like




 
Correction to my previous reply
I was in a rush when i submited the reply and i missed many things. I will change the course of steps a little although the core ideas remain the same.

Creating your DLL module
1. Start by creating a DLL project
2. Add a new unit where you will define your interface
3. Add a new unit where you will define the class that implements the interface


Here is sample code for your DLL module
DLL project unit
Code:
library MyDLL;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  SysUtils,
  Classes,
  MyInterfaceUnit in 'MyInterfaceUnit.pas',
  MyInterfaceImplementation in 'MyInterfaceImplementation.pas';

{$R *.res}

begin
end.


interface unit code
Code:
unit MyInterfaceUnit;

interface

type

    IMyInterface=interface
    //[press Ctrl+Shift+G to generate interface unique ID]
      procedure MyProcedure();        stdcall;
      function  MyFunction():Boolean; stdcall;
    end;

    //Define the type of function you will use to create 
    //objects that implement this interface
    TCreateMyObject=function :IMyInterface;

implementation

end.

interface implementation class unit
Code:
unit MyInterfaceImplementation;

interface

uses
   MyInterfaceUnit;

type
    TMyInterfaceClass=class(TInterfacedObject,IMyInterface)
    public
      procedure MyProcedure();        virtual; stdcall;
      function  MyFunction():Boolean; virtual; stdcall;
    end;

implementation
uses
    Dialogs;

procedure TMyInterfaceClass.MyProcedure();
begin
    ShowMessage('MyProcedure: Your Code');
end;

function TMyInterfaceClass.MyFunction():Boolean;
begin
    ShowMessage('MyFunction: Your Code');
    result:=true;
end;


//Define a function that will create your object
//as you will see below this function is the only
//you will need to export
function CreateMyObject():IMyInterface;
begin
    result:=TMyInterfaceClass.Create();
end;

//dont forget to export CreateMyObject
exports
   CreateMyObject;

end.



Now testing your DLL
1. Start with creating a VCL form application project
2. Add MyInterfaceUnit to the project
3. Change the form unit to test your DLL

Here is sample code :

Code:
unit MyForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, MyInterfaceUnit;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
     my:IMyInterface;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
   nHandle:Cardinal;
   createFunc:TCreateMyObject; //pointer to creation function
begin
     //Load the library
     nHandle:= LoadLibrary('MyDLL.dll');

     if nHandle<>0 then 
     begin
         createFunc:=TCreateMyObject(GetProcAddress(nHandle,'CreateMyObject'));
         if Assigned(createFunc) then
              my:=createFunc()
         else
             ShowMessage('MyDLL.dll does not export CreateMyObject');
     end
     else
         ShowMessage('Could not load library');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
     //Calling myProcedure defined in DLL via myInterface
     my.MyProcedure;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
     //Calling MyFunction defined in DLL via myInterface
     my.MyFunction;
end;


I hope this will help you.



 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top