Translate to:

Online Delphi Training

Learn LIVE
From The Comfort Of Your Home
Start Immediately!

+1 (678) 921-0644

How To Create And Call A Dynamic Link Library (DLL) In Delphi

Introduction To The Dynamic Link Library (DLL)

A Dynamic Link Library (DLL) is an executable file with a .DLL extension that may contain procedures, functions or resources that can be shared by multiple programs. Even if several programs call the same DLL, it is only loaded once in memory saving system resources. That is one of its major advantages.

A DLL can be used to store resources. For example, you can create a DLL of images that you can then use in your applications. Or, you can use DLLs to provide multi-lingual support for an application by creating several versions of a DLL for the various supported languages and then calling them as needed at run time.

You may have a complex application that is constantly being updated. By using DLLs in this situation, you can save your users a great deal of time and frustration. Instead of having to recompile and deploy the entire application with every new update, you can simply provide a new DLL to replace an older version. To use a DLL in this way, you must include all the methods found in the old DLL in the new version, and not change any of the original parameters.

Online Delphi Training offers customized DLL training. You can also sign up for the following classes:

DLL Example

In this example, I will create a basic DLL that holds some conversion functions.

Our DLL example will export the following six conversion functions. Each of the functions will accept one parameter of type double and will output a result of type double:

  1. function CelciusToFahrenheit (Value: double): double; stdcall;
  2. function FahrenheitToCelcius (Value: double): double; stdcall;
  3. function KilogramsToPounds (Value: double): double; stdcall;
  4. function PoundsToKilograms (Value: double): double; stdcall;
  5. function KilometersToMiles (Value: double): double; stdcall;
  6. function MilesToKilometers (Value: double): double; stdcall;

Whenever you declare a procedure or function, you can also specify a calling convention which determines the order in which parameters are passed to the routine. This also affects the removal of the parameters from the stack, error and exception handling and the way the registers are used for passing the parameters.

The directives to specify a calling convention are: register (the default), stdcall, safecall, cdecl, and pascal. If you plan to call your DLL from other Delphi applications only, you can go with the default register calling convention. We will use the stdcall to utilize the standard Win32 parameter-passing which passes parameters from right to left.

To start a new DLL project, click on File, New and Other. In the New Items dialog, select "DLL Wizard" and click on "OK."

DLL using Delphi

The following project is created:

As you can see, this wizard did not really do that much. But, please take note of the important comment it inserted for us.

For Win32, if you have a DLL that exports functions that pass long strings or dynamic arrays as parameters or function results, the DLL and its calling applications or DLLs must all use the ShareMem unit, and it must be listed as the first unit in the Uses clause for both the DLL and the project source file (.DPR) of the calling application.

This also applies if you allocate memory with New or GetMem and deallocate it in another module by calling Dispose or FreeMem. The same is true if you pass strings that are nested in records or objects (instead of passing them directly). ShareMem is the interface unit for the memory manager BORLANDMM.DLL, which allows the sharing of dynamically allocated memory. BORLANDMM.DLL must be deployed with your application or DLL if they use ShareMem. In this example, we will not be needing ShareMem.

Following is the full code for the "ConvertDLL.dll" which will get created when you compile the library:

library ConvertDLL;

{ 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. }


{$R *.res}

function CelciusToFahrenheit(value: double): double; stdcall;
    Result := ((value * 9) / 5) + 32;

function FahrenheitToCelcius(value: double): double; stdcall;
    Result := ((value - 32) * 5) / 9;

function KilogramsToPounds(value: double): double; stdcall;
    Result := value * 2.20462262184878;

function PoundsToKilograms(Value: double): double; stdcall;
    Result := value * 0.45359237;

function KilometersToMiles(Value: double): double; stdcall;
    Result := value * 0.621371192237334;

function MilesToKilometers(Value: double): double; stdcall;
    Result := value * 1.609344;



Calling The DLL

Included in the download for this project is a demo application that calls the DLL we just created. I will only cover the relevant portions of the application. You can download and review the entire project. You may want to create a different application and perform different calls.

Following are the declarations of the functions in the demo application:


{$R *.dfm}

{ TfrmMain }

function CelciusToFahrenheit(Value: double): double; stdcall;
    external 'ConvertDLL.dll';
function FahrenheitToCelcius(Value: double): double; stdcall;
    external 'ConvertDLL.dll';
function KilogramsToPounds(Value: double): double; stdcall;
    external 'ConvertDLL.dll';
function PoundsToKilograms(Value: double): double; stdcall;
    external 'ConvertDLL.dll';
function KilometersToMiles(Value: double): double; stdcall;
    external 'ConvertDLL.dll';
function MilesToKilometers(Value: double): double; stdcall;
    external 'ConvertDLL.dll';

The only new thing here is the addition of "external 'ConvertDLL.dll.'" This example assumes that the DLL is in the same path as the executable. If it is not found, you will get an error to that effect when you try to run the application. The "external" directive imports the routines from the DLL.

Following is the main part of the application:

procedure TfrmMain.btnConvertClick(Sender: TObject);
  value : double;
 If (eValue.Text <> '') and (cbFrom.ItemIndex in [0..5]) then
  value := StrToFloatDef (eValue.Text, 0);
  With eResult do
      Case cbFrom.ItemIndex Of
          0: Text := FloatToStr(CelciusToFahrenheit(value)) + ' degress Fahrenheit';
          1: Text := FloatToStr(FahrenheitToCelcius(value)) + ' degrees Celcius';
          2: Text := FloatToStr(KilogramsToPounds(value)) + ' Pounds';
          3: Text := FloatToStr(KilometersToMiles(value)) + ' Miles';
          4: Text := FloatToStr(MilesToKilometers(value)) + ' Kilometers';
          5: Text := FloatToStr(PoundsToKilograms(value)) + ' Kilograms';
 else begin
            MessageDlg ('Please make a valid selection', mtError, [mbOK], 0);

The value entered in the TEdit control is coverted to type Float and passed as the parameter of the relevant function. The result is converted back to type string and displayed in another TEdit control. The rest of the code is for overall functionality. How you actually code it and display it is up to you, of course. This is a quick example to demonstrate the concepts.

Do you have any comments about this topic?

Click on: Post Comments/Questions

To download the project click on: Download DLL example using Delphi

©2005-2006 Business-IQ