Thursday, July 31, 2008

How to create DLL s using Delphi


Introduction

DLL means Dynamic Link Libraries. As the name implies , dll is a collection of functions and procedures in a place which can be used in other applications. Basic idea of creating DLLs is to share functions and procedures across languages. DLL files will have an extension of .dll.

How to create a dll using Delphi

It's not so hard to create a dll as you heard. Using Delphi it's very easy. Select the menu File -> New -> Other... from Delphi IDE. This will open a dialog box. From there select the "DLL Wizard" icon . A new project will be opened with a new unit. This unit file will be little bit different from the normal unit files. In the normal units , the first line will contain a keyword unit and the respective unitname. But the unit created in dll , the first keyword will be library instead of unit as given below.

library DLLProject;

uses
SysUtils,
Classes;


{$R *.RES}

begin
end.

Now you can add as many functions and procedures under the uses clause. The functions and procedures that are required to be called from other applications should be exported using the clause Exports. The name used along with the library clause will become the name of the dll. In this case our dll will be DLLProject.dll


Suppose you have 3 functions as shown below.

Function SubFunc():Integer;
begin
...
end;

Procedure SubProc();
begin
...
end;

Function MainFunc():Integer;
begin
...
SubFunc;
SubProc;
...
end;

Exports
MainFunc;

begin
end;


Here we have 2 functions and one procedure . The MainFunc is the main function which calls other 2 functions and here we are exporting MainFunc only. That means MainFunc is the only function which can be called from outside. If you need to export any other function or procedure , you have to include it under the Exports clause.

Dll loading

Now we can see how these dll [exported] functions can be called from other applications. The dll function/procedure has to be declared in the global section [before implementation section] of the unit file where the it has to be called. The syntax should be

var
procedure MainFunc ():Integer; external 'DLLProject.dll';

Implementation.

end;

This kind of loading a dll is called static loading. Because compiler try to load the dll when it loads the application itself. So if the dll is missing in the search path , you'll get an erroro message while starting your application itself.

Now we'll see another kind of dll loading named Dynamic loading. This kind of loading require extra commands to load dll , call your dll function and release the dll from memory. The dll will be loaded in the memory whenever you call the LoadLibrary function. It won't be loaded when your application starts. So if the dll is missing in your search path, you won't get any error message during the start up of your application.

The dll should be loaded using the command LoadLibrary which returns the handle to the dll once it's loaded to the memory. If there is any problem in loading, the handle will return 0.
Once dll is loaded properly in to the memory, we have to gather the address of the function\procedure to be called. This can be done using the function GetProcAddress which returns the address of the dll function. To receive the return value , you have to have a variable of type function or procedure [TDllAddr = function : Integer; ].

Have a look at the example shown below.

type

TDllAddr = function : Integer;

var
DllAddr : TDllAddr;

begin

DllHandle := LoadLibrary("DLLProject.dll");
if DllHandle <> 0 then
begin
@DllAddr := GetProcAddress(DllHandle , 'MainProc');
DllAddr(); // Calling dll function
end;

end;

Finally, the memory allocated for the dll has to be explicitly released using the FreeLibrary function.

Note : The dll function parameters should be windows types. If you have any String type parameter in dll function/procedure , then you have include ShareMem unit in the dll. Not only that, Sharemem unit should be the first unit in the uses clause.

No comments: