Creating a DLL library in Delphi. Creating and Using Dynamic Link Libraries (DLLs) in Delphi



Introduction

Due to the rapid development of programming technologies, more and more people are faced with the problem of increasing the capabilities of their programs. This article is devoted precisely to this issue, namely, DLL programming in Borland Delphi. In addition, since we will touch on questions about the use DLLs, then along the way we’ll touch on importing functions from other people’s DLLs (including system ones, i.e. WinAPI).

DLL Application Areas

So, why are DLLs needed and where are they used?.. Let's list just some of the areas of their application:

Separate libraries Contain useful for programmers additional functions. For example, functions for working with strings, or complex libraries for converting images. Resource storage DLLs can store not only programs and functions, but also all kinds of resources - icons, pictures, string arrays, menus, etc. Support libraries Examples include libraries of such well-known packages as: DirectX, ICQAPI (API for ICQ), OpenGL, etc. Parts of a program For example, program windows (forms), etc. can be stored in a DLL. Plugins This is where the real scope for a programmer's thoughts is! Plugins are additions to a program that expand its capabilities. For example, in this article we will look at the theory of creating a plugin for your own program. DLL shared resource ( Dynamic Link Library) can be used by several programs or processes at once (so-called sharing - shared resource)

Brief description of functions and techniques for working with DLLs

So, what techniques and functions do you need to use to work with DLLs? Let's look at two methods for importing functions from a library:

1 way. Binding a DLL to a program.

This is the simplest and easy method to use functions imported from DLLs. However (and this should be noted) this method has a very significant drawback - if the library that the program uses is not found, then the program simply will not start, giving an error and reporting that the DLL resource was not found. And the library will be searched: in the current directory, in the program directory, in the WINDOWS\SYSTEM directory, etc. So, first, the general form of this technique:


FunctionName (or ProcedureName) the name of the function (or procedure) that will be used in your program; Par1, Par2, ... names of function or procedure parameters; Par1Type, Par2Type, ... types of function or procedure parameters (for example, Integer); ReturnType return type (function only); stdcall directive, which must exactly match the one used in the DLL itself; external "DLLNAME.DLL" directive specifying the name of the external DLL from which it will be imported this function or procedure (in in this case- DLLNAME.DLL); name "FunctionName" ("ProcedureName") directive specifying the exact name of the function in the DLL itself. This is an optional directive that allows a function to be used in a program that has a name other than the true one (which it has in the library); index FunctionIndex (ProcedureIndex) directive indicating the index number of a function or procedure in a DLL. This is also an optional directive.

This is a much more complex, but also more elegant method. It does not have the disadvantage of the first method. The only thing that is unpleasant is the amount of code required to implement this technique, and the difficulty is that the function imported from the DLL is accessible only when this DLL is loaded and is in memory... An example can be found below, but for now - short description WinAPI functions used by this method:

LoadLibrary(LibFileName: PChar) Loads the specified library LibFileName into memory. On success, the function returns a handle (THandle) to the DLL in memory. GetProcAddress(Module: THandle; ProcName: PChar) reads the address of the exported library function. On success, the function returns a handle (TFarProc) to the function in the loaded DLL. FreeLibrary(LibModule: THandle) invalidates the LibModule and frees the memory associated with it. It should be noted that after calling this procedure, the functions of this library are no longer available.

Practice and examples

Well, now it’s time to give a couple of examples of using the above methods and techniques:

Example 1. Linking a DLL to a program


Now the same thing, but in the second way - with dynamic loading:


Note:

You should refrain from using the string type in library functions because There are problems with "memory sharing" when using it. You can read more about this (though in English) in the text of the empty DLL project that Delphi creates (File -> New -> DLL). So better use PChar and then convert it to if necessary string function StrPas.

Well, now let’s look at the DLL itself:

Example 3. Source of the project MYDLL.DPR


Accommodation in Resource DLLs and forms

A DLL can contain not only functions, but also cursors, pictures, icons, menus, text strings. We will not dwell on this. I will only note that to load a resource you need to load the DLL, and then, having received its descriptor, load the resource itself with the appropriate function (LoadIcon, LoadCursor, etc.). In this section, we will only briefly touch on the placement of application windows (i.e. forms in Delphi) in DLLs.

To do this you need to create a new DLL and add to it new uniform(File -> New -> DLL, and then File -> New Form). Next, if the form is a dialog box ( modal form(bsDialog)), then add to DLL following function (let's say the form is called Form1 and its class is TForm1):

Example 4: Placing a form in a DLL


If you need to place a non-modal form in a DLL, then you need to create two functions - opening and closing the form. In this case, you need to force the DLL to remember the handle to this form.

Creating plugins

Here we will not consider plugins in detail, because... The examples already given above will help you easily understand the lion's part of DLL programming. Let me just remind you that a plugin is an addition to the program that expands its capabilities. At the same time, the program itself must provide for the presence of such additions and allow them to fulfill their purpose.

That is, for example, to create a plugin for graphic editor that would perform image conversion, you need to provide at least two functions in the plugin (and, accordingly, call these functions in the program) - a function that would return the name of the plugin (and/or its type) in order to add this plugin to the menu ( or in the toolbar), plus the main function is to transmit and receive images. Those. first the program searches for plugins, then for each found one it calls its identification function with a strictly defined name (for example, GetPluginName) and adds the desired item to the menu, then, if the user has selected this item, it calls the second function, which passes the input image (or file name, containing this image), and this function, in turn, processes the image and returns it in a new form (or the file name with a new image). That's the essence of the plugin... :-)

Epilogue

This article shows the basics of using and creating DLLs in Borland Delphi. If you have questions, send them to me by email:

Dear colleagues!

In this article I will try to answer the questions: What is DLL? What is it for? And how to create and use DLL with help Delphi.

What is DLL?

Dynamic Link Library or for short DLL is a library that contains a set of data or functions for use in other programs.

Areas of use:

  • Storage of resources: icons, sounds, cursors, etc. Save on size executable files combining resources into a single library.
  • Accommodation individual modules programs and interface forms. We get the opportunity to partially update the application, and with a dynamic connection, it is possible to update modules without restarting the main program.
  • Use as plugins (PlugIn). We provide the opportunity to expand the functionality of the application without rewriting the main program code.
  • The library can be used in different programming languages, regardless of the language in which it was written.

Creation own library DLL.

To create a library, go to the menu File -> Other and choose Delphi Projects -> Dynamic-link Library.
A code text with a template for creating a library will open:

Library Project1; uses System.SysUtils, System.Classes; ($R *.res) begin end.

Resource placement

Let's add an icon to the library, which we will use later in the main program.
How to add resources to a project is described in detail in the article.

Let’s add an “About the program” form.
Click File -> New -> VCL Form. Let's add text and an "OK" button:

Let's add a function that will display the standard MessageBox with a question, buttons “Yes”, “No” and with a result in the form True or False.

Function YesNoDlg(const Question: PChar): boolean; stdcall; begin Result:= (MessageBox(0, Question, "Confirmation", MB_YESNO + MB_ICONQUESTION) = ID_YES); end;

Pay attention to the keyword stdcall. It determines exactly how parameters and results will be passed when calling functions. You can read more on the Calling Agreement wiki page.

We will also add a procedure that will be used as a plugin for the main program. Which will add an “About the program” button to the main program menu to open the window we created.
Procedure code:

Procedure PlugIn(Form: TForm); stdcall; var i: integer; mi: TMenuItem; begin for i:= 0 to Form.ComponentCount - 1 do begin if (Form.Components[i].ClassName = "TMenuItem") and (Form.Components[i].Name = "miHelp") then begin mi:= TMenuItem .Create(Form.Components[i]); mi.Caption:= "About the program"; mi.OnClick:= fmAbout.onAboutButtonClick; TMenuItem(Form.Components[i]).Add(mi); Exit; end; end; end;

The form of the program is passed to the procedure as a parameter. We check whether there is a menu item named “ miHelp"and if the menu is found, then add our button to it.

Now we will indicate which functions and procedures can be used from our library.
Let's add the line:

Exports PlugIn, YesNoDlg;

Let's compile the function Project -> Build or using hotkey Shift+F9.
If there are no errors in the code, then a file with the extension should appear in the project folder DLL.

Now let's move on to creating an application that will use our library.

Let's create a form in the application Main in which we will add a component with the following buttons: Program -> Exit and Help. For the last one, let's set a name - miHelp:

Let's move on to the form code.

Functions from the library DLL can be connected in two ways:
Static— the library is connected when the program starts. If the library or function name is not found, the program will generate an error and will not run.
Dynamic— the library is connected either immediately before calling a function or upon a specific event.

Let's consider the static connection method:

Type TfmMain = class(TForm) MainMenu: TMainMenu; miProgram: TMenuItem; miExit: TMenuItem; miHelp: TMenuItem; procedure FormCreate(Sender: TObject); procedure miExitClick(Sender: TObject); private public end; procedure PlugIn(Form: TForm); stdcall; external "SampleDLL.dll"; var...

Keyword external indicates that this function is connected from an external library.

For the event onCreate form, add a procedure call PlugIn:

Procedure TfmMain.FormCreate(Sender: TObject); begin PlugIn(Self); end;

As a parameter Form we pass the current form to the procedure (keyword Self).

When starting the program, we should have the “About the program” item in the “Help” section of the main menu.

Let's move on to the dynamic connection method.

We will need three functions WinApi:

LoadLibrary
Loads the library into the computer's memory. As a result, it returns a pointer to the library in memory. In case of error, it will return 0.

LoadLibrary(lpLibFileName: LPCWSTR): HMODULE;

lpLibFileName— Library file name.

GetProcAddress
Find a function in a library by name. The result will be a function pointer. If the function is not found, it will return nil.

GetProcAddress(hModule: HMODULE; lpProcName: LPCSTR): FARPROC;

hModule
lpProcName— Function name.

FreeLibrary
Unloads the library from the computer's memory. The result will be True in case of success and False in case of error.

FreeLibrary(hLibModule: HMODULE): BOOL;

hLibModule— Pointer to the loaded library.

Now with the help dynamic method We’ll get the resources, our icon, and add a function call to the “Exit” button YesNoDlg to confirm the program is closed.
Add the code to the same onCreate event:

Procedure TfmMain.FormCreate(Sender: TObject); var DLLHandle: THandle; begin PlugIn(Self); DLLHandle:= LoadLibrary("SampleDLL.dll"); if DLLHandle = 0 then raise Exception.Create("Could not include library 'SampleDLL'!"); try Self.Icon.LoadFromResourceName(DLLHandle, "my_icon"); finally FreeLibrary(DLLHandle); end; end;

And for the event onClick menu item "Exit":

Procedure TfmMain.miExitClick(Sender: TObject); var DLLHandle: THandle; Dlg: function(const Question: PChar): boolean; stdcall; begin DLLHandle:= LoadLibrary("SampleDLL.dll"); if DLLHandle = 0 then raise Exception.Create("Could not include library 'SampleDLL'!"); try @Dlg:= GetProcAddress(DLLHandle, "YesNoDlg"); if not Assigned(@Dlg) then raise Exception.Create("The function named "YesNoDlg" was not found in the library "SampleDLL"!"); if Dlg("Exit the program?") then Close; finally FreeLibrary(DLLHandle); end; end;

If you wrote everything correctly, then after starting the program the form icon should change, the “About the program” button should be added, when clicked on it the form will show About and when you press the exit button, the program will ask for confirmation: “Exit the program?”

I hope you find this useful small example taking advantage of opportunities DLL libraries.
The project sources can be downloaded.

Due to the rapid development of programming technologies, more and more people are faced with the problem of increasing the capabilities of their programs. This article is devoted precisely to this issue, namely, DLL programming in Borland Delphi. In addition, since we will touch on issues related to the use of DLLs, we will also touch upon importing functions from foreign DLLs (including system ones, i.e. WinAPI).

DLL Application Areas

So, why are DLLs needed and where are they used?.. Let's list just some of the areas of their application:

  • Individual libraries, containing additional functions useful for programmers. For example, functions for working with strings, or complex libraries for converting images.
  • Resource storage. A DLL can store not only programs and functions, but also all kinds of resources - icons, pictures, string arrays, menus, etc.
  • Support Libraries. As an example, we can cite libraries of such well-known packages as: DirectX, ICQAPI(API for ICQ), OpenGL etc.
  • Parts of the program. For example, you can store program windows (forms), etc. in a DLL.
  • Plugins(Plugins). - This is where the real scope for a programmer’s thoughts is! Plugins are additions to a program that expand its capabilities. For example, in this article we will look at the theory of creating a plugin for your own program.
  • Shared resource. DLL ( Dynamic Link Library) can be used by several programs or processes at once (the so-called. sharing- shared resource)

Brief description of functions and techniques for working with DLLs

So, what techniques and functions do you need to use to work with DLLs? Let's look at two methods for importing functions from a library:

1 way. Binding a DLL to a program. This is the simplest and easiest method for using functions imported from a DLL. However (and this should be noted) this method has a very significant drawback - if the library that the program uses is not found, then the program simply will not start, giving an error and reporting that the DLL resource was not found. And the library will be searched: in the current directory, in the program directory, in the WINDOWS\SYSTEM directory, etc.
So, first, the general form of this technique:

implementation
...
function FunctionName(Par1: Par1Type; Par2: Par2Type; ...): ReturnType; stdcall; external"DLLNAME.DLL" name"FunctionName" index FuncIndex;
// or (if not a function, but a procedure):
procedure ProcedureName(Par1: Par1Type; Par2: Par2Type; ...); stdcall; external"DLLNAME.DLL" name"ProcedureName" index ProcIndex;

Here: FunctionName(or ProcedureName) - the name of the function (or procedure) that will be used in your program;
Par1, Par2, ...- names of function or procedure parameters;
Par1Type, Par2Type, ...- types of function or procedure parameters (for example, Integer);
ReturnType- return value type (for function only);
stdcall- a directive that must exactly match the one used in the DLL itself;
external "DLLNAME.DLL"- a directive indicating the name of the external DLL from which the given function or procedure will be imported (in this case - DLLNAME.DLL);
name "FunctionName" ("ProcedureName")- a directive indicating the exact name of the function in the DLL itself. This is an optional directive that allows a function to be used in a program that has a name other than the true one (which it has in the library);
index FunctionIndex(ProcedureIndex)- a directive indicating the sequence number of a function or procedure in a DLL. This is also an optional directive.

Method 2. Dynamic loading of DLLs. This is a much more complex, but also more elegant method. It does not have the disadvantage of the first method. The only thing that is unpleasant is the amount of code required to implement this technique, and the difficulty is that the function imported from the DLL is accessible only when this DLL is loaded and is in memory... You can see the example below, but for now - a short description of the WinAPI functions used by this method:

LoadLibrary(LibFileName: PChar) - loads the specified library LibFileName into memory. On successful completion, the function returns a handle ( THandle) DLL in memory.
GetProcAddress(Module: THandle; ProcName: PChar) - reads the address of the exported library function. On successful completion, the function returns a handle ( TFarProc) functions in the loaded DLL.
FreeLibrary(LibModule: THandle) - invalidates the LibModule and frees the memory associated with it. It should be noted that after calling this procedure, the functions of this library are no longer available.

Practice and examples

Well, now it’s time to give a couple of examples of using the above methods and techniques:

Now the same thing, but in the second way - with dynamic loading:

(...Here goes the file header and the definition of the form TForm1 and its instance Form1)

var
Form1: TForm1;
GetSimpleText: function(LangRus: Boolean): PChar;
LibHandle: THandle;

procedure Button1Click(Sender: TObject);
begin
(“Cleaning” the function address from “dirt”)
@GetSimpleText:= nil;
(We are trying to load the library)
LibHandle:= LoadLibrary("MYDLL.DLL");
(If everything is OK)
if LibHandle >= 32 then begin
(...then we are trying to get the address of the function in the library)
@GetSimpleText:= GetProcAddress(LibHandle,"GetSimpleText");
(If everything is OK here too)
if @GetSimpleText<>nil then
(...then call this function and show the result)
ShowMessage(StrPas(GetSimpleText(True)));
end;
(And don’t forget to free up memory and unload DLL)
FreeLibrary(LibHandle);
end;

NOTE : You should refrain from using the string type in library functions because There are problems with "memory sharing" when using it. You can read more about this (though in English) in the text of the empty DLL project that Delphi creates (File -> New -> DLL). So it's better to use PChar and then convert it to string using StrPas function if necessary.

Well, now let’s look at the DLL itself:

Placing resources and forms in DLLs

A DLL can contain not only functions, but also cursors, pictures, icons, menus, and text strings. We will not dwell on this. I will only note that to load a resource you need to load the DLL, and then, having received its descriptor, load the resource itself with the appropriate function (LoadIcon, LoadCursor, etc.). In this section, we will only briefly touch on the placement of application windows (i.e. forms in Delphi) in DLLs.

To do this, you need to create a new DLL and add a new form to it (File -> New -> DLL, and then File -> New Form). Next, if the form is a dialog box (modal form (bsDialog)), then add the following function to the DLL (let's say the form is called Form1, and its class is TForm1):

If you need to place a non-modal form in a DLL, then you need to create two functions - opening and closing the form. In this case, you need to force the DLL to remember the handle to this form.

Creating plugins

Here we will not consider plugins in detail, because... The examples already given above will help you easily understand the lion's part of DLL programming. Let me just remind you that a plugin is an addition to the program that expands its capabilities. At the same time, the program itself must provide for the presence of such additions and allow them to fulfill their purpose.

That is, for example, to create a plugin for a graphic editor that would perform image conversion, you need to provide at least two functions in the plugin (and, accordingly, call these functions in the program) - a function that would return the name of the plugin (and /or its type) to add this plugin to the menu (or toolbar), plus the main function - transmitting and receiving images. Those. first the program searches for plugins, then for each found one it calls its identification function with a strictly defined name (for example, GetPluginName) and adds the desired item to the menu, then, if the user has selected this item, it calls the second function, which passes the input image (or file name, containing this image), and this function, in turn, processes the image and returns it in a new form (or the file name with a new image). That's the essence of the plugin... :-)

Epilogue

This article shows the basics of using and creating DLLs in Borland Delphi. If you have questions, send them to me by email: [email protected], and even better - write in the conference on this site so that other users can see your question and try to answer it!

Karikh Nikolay. Moscow region, Zhukovsky

A DLL library allows you to combine reusable code into one whole. Functions from DLL libraries can be linked dynamically at runtime, in contrast to functions from Delphi packages, which are linked statically at the compilation stage of the application.

In order to create a DLL library, first you need to execute the File|New|Other menu command and select the DLL Wizard element on the New page of the New Item dialog.

The DLL Wizard will automatically create a blank template for the DLL. Unlike a regular module, which begins with the unit keyword, a DLL library module begins with the library keyword. The uses section of the DLL module requires the inclusion of only two packages: SysUtils and Classes.

Creating a DLL function consists of several steps:

1. First, in the module implementation section, you must enter the function signature and program the code that the function executes.

3. Finally, a function that is supposed to be used not only inside a module, but also called from other applications, should be declared as exportable in the exports section.

Functions from a DLL can be called both from applications developed in Delphi and from applications written in other programming languages, such as C++.

The order of allocating memory for parameters and freeing it is different for different languages programming. To avoid a run-time error, the function declaration in the DLL and the function declaration in the application must use the same parameter passing mechanism. When declaring a procedure or function, one of the following mechanisms for passing parameters can be specified:

The method of passing parameters is indicated with a semicolon after the function description. For example:

function F1 (X, Y, Z: Real]: Real; stdcall;.

Various ways parameter passes define the order in which parameters are passed (from left to right or from right to left), and also indicate who will deallocate stack memory (the called procedure or the calling procedure). When using DLLs as components called from applications in other programming languages, you should use the appropriate call modifier. For C++ applications, the stdcall call modifier is used.

In order for a function described in a DLL to be called from another application, the function must be exported. The list of all exported functions is indicated in the exports section, separated by commas

and ends with a semicolon. Exporting functions can be done in three ways:

By the function name used in the DLL;

By function name specified as export name;

By the index assigned to the function.

In order to assign a certain index to a function, it should be specified in the exports section after the function name with keyword index.

In order for the exported function to be called by a name different from the name used in the DLL library, in the exports section after the function name, you must specify the keyword name and the new export name for this function.

DLL - the library is not an executable module. To obtain its code, it is enough to compile the project.

library project;

SysUtils, Classes;

function F1(X, Y: Integer): Integer; stdcall;

Statically linking a DLL library

The DLL can be linked either statically or dynamically. When you include a DLL, it is loaded into application memory.

With a static connection, the DLL is loaded once when the application starts. Throughout the application's execution, the name of a function imported from a DLL that was statically linked points to the same function (the entry point to the DLL) in the same DLL. All functions from the DLL that will be used initially in the application must be declared as external. In this case, you should specify, if necessary, a call modifier. If a function is called by index, it must be given the name used in the application and the index of the function in the DLL.

ads external functions executed in the implementation section before using these functions.

Declaration of external functions with the external keyword specifies that static linking will be used.

TForml = class(TForm)

Editl: TEdit; [Field for entering the first value)

Edit2: TEdit; (Field for entering the second value)

Edit3: TEdit; (Field to display the result

execute a function from a DLL)

Buttonl: TButton; (A call is made to the function used by name)

Button2: TButton; [A function call is made using the index)

procedure ButtonlClickfSender: TObject);

procedure Button2Click(Sender: TObject);

(Private declarations)

(Public declarations)

(Declaration of exported functions)

function Fl (i: Integer; j: Integer): Integer; stdcall;

external "Projectl.dll";

function F2 (i: Integer; j: Integer): Integer; stdcall;

external "Projectl.dll index 2;

procedure TForml.ButtonlClick(Sender: TObject);

(Call exported function)

Edit3.Text:=IntToStr(Fl(StrToInt(Editl.Text),StrToInt(Edit2.Text) ));

procedure TForml.Button2Click(Sender: TObject);

Edit3.Text:=JntToStr(F2(StrToInt(Editl.Text),StrToInt(Edit2.Text)));

Dynamically linking a DLL library

Unlike statically linking a DLL, which occurs when the application loads, dynamically linking a DLL can be done at any point in the program's execution. After calling a function from a DLL, you can disable it. When using several DLLs simultaneously, this provides significant memory savings. Windows API functions are used to dynamically connect a DLL library. Windows API - this is a set standard features, used to implement interaction with the operating system.

When calling a function from a dynamically linked DLL, instead of defining the function name as external in case of static linking, you should define new type, corresponding to the type of the function being called, and create a variable of this type.

To make a function call from a dynamic link DLL, run the following actions:

1. Create a new type. corresponding to the type of the called function (the name of the new type can be entered after the type section).

For example:

TMyFl=function(i,j:Integer):Integer; stdcall;

2. In the var section of the interface section of the module, create a variable of the created function type. For example: MyFl: TMyFl;

3. Before loading the DLL, declare type variable Integer, which will contain the descriptor of the library being connected.

4. Call the LoadLibrary method, which loads the DLL. For example; h:=LoadLibrary("Projectl.dll");

5. Check if the library connection is successful. If the DLL name is incorrect or the DLL is not found, the LoadLibrary function will return 0.

6. If you successfully connect the DLL library, you next need to get the function address. For this purpose it is used Windows function API GetProcAddress, the parameters of which are the descriptor of the DLL library and the name of the connected function. For example: @MyFl: =GetProcAddress(h, "Fl");

7. If the function address is received, then the value of the address (in our example @MyFl) should not be equal to nil.

8. At this point, you can call a function from a dynamically linked DLL.

9. To free and therefore unload the DLL, call the FreeLibrary method, which disables the DLL.

Windows, Messages, SysUtils, Variants, Classes, Graphics,

Controls, Forms, Dialogs, StdCtrls;

TForml = class(TForm)

Button3: TButton;

procedure Button3Click

procedure TForml.Button3Click(Sender: TObject);

h:=LoadLibrary("Projectl.dll");

if h<>0 then

@MyFl:=GetProcAddress(h,"Fl");

if @MyFl<>nil then

Edit3.Text:=IntToStr(MyFl(StrToInt(Editl.Text),

StrToInt(Edit2.Text)));

Using a DLL to call common modal dialogs.

The result of executing a procedure from a DLL library may be the display of some modal dialog. To do this, create a form object in the exported method, display it as a modal dialog, and then delete the form object. In this case, the form itself should include a challenge Close method to end the dialogue.

To create a form, use the Create method, which is passed a pointer to parent form- form calling application. This parameter is passed to the called DLL function.

library project;

Unitl_DLL in "Unitl_DLL.pas" (Forml);

procedure MyModalForm (var Z:Integer ;F:TForm1); stdcall;

Form1:=TForml.Create(F);

(The F parameter is passed when calling the procedure and contains a pointer

to the parent form - the form of the calling application)

In the environment Delphi programming There are built-in tools for quickly creating DLL libraries.

Let's create a library containing the function to be specific

GetArea(a, b, c: REAL):REAL.

This function takes as input the lengths of the sides of the triangle. The function returns the area of ​​the given triangle:

p:=(a+b+c)/2;

Result:=SQRT(p*(p-a)*(p-b)*(p-c))

Launch Delphi, and then we act unconventionally. Select menu items FileNewOther, in the window that opens on the N tabewclick on the DLL W iconizard. ( algorithm depends on version)

This creates a template DLL file. It is very similar to a regular module (unit) Delphi, just starts with the operatorLibrary. Save the project under the name that the DLL will have in the future, sayGetA. NameGetAreacannot be used - it is already occupied by the function name.

Now after the operatorUSESwe write the text of our function, but with some changes in the title:

FUNCTION GetArea(a, b, c:REAL):REAL;export;

The EXPORT keyword indicates that the function is exportable and will be visible from external programs.

After the text of the function we will add

GetArea;

The EXPORTS statement lists all procedures and functions exported from the library. This is a kind of catalog of our library.

It is impossible to run the library; it can only be compiled. To do this, select the menu item Project → Build. If everything was done correctly, a file named geta.dll will be created on the disk in the current directory. This is our library.

Important Note: There is a certain subtlety when passing parameters of type STRING to procedures and functions located in the library.

In order to be able to pass parameters of the STRING type, you will have to specify the connection of the ShareMem module in the USES statements of both the library and the program that calls it, and it is also necessary so that this module comes first in the list. Moreover, along with the library you will have to include the file borlndmm.dll (it is included in the Delphi distribution). It’s easy to avoid this situation: you should use ShortString data types for text type parameters (this is regular string, but up to 255 characters long) and PChar (pointer to a text string).

Call dll

There are two ways to call procedures and functions from a DLL. In the first case, we know in advance, at the stage of program development, which DLL we will connect to it (most often we create this DLL ourselves). In the second case, we connect to an arbitrary library, including a “foreign” one.

Static linking

To implement the first method, called static linking, create a new regular application, place three input fields LabeledEdit1...LabeledEdit3, a button and a Tlabel component on the form. After the IMPLEMENTATION statement, add a line that imports the GetArea function from the geta.dll library:

Function GetArea(a,b,c:real):REAL; FAR; EXTERNAL "geta";

The word EXTERNAL indicates that the body of this function is located in the library with the specified name, and the word FAR specifies the use of “long” four-byte addresses, which is necessary because calling program is on one page of memory, and the DLL is on another. Of course, the geta.dll file must be placed in the same directory where all the files of the current application are located.

In the button click handler, you need to create an array and pass it to the library function, and display the result on the screen:

procedure TForm1.Button1Click(Sender: TObject);