Creating a dll library in Delphi. Creation and development of dynamic libraries (DLLs) in Delphi. We add our Viewer to all DLLs

To create a new DLL in Delphi, select the menu command File > New > Other. At the panel Items Categories vikna New Items select university Delphi Projects, then click on the element Dynamic-link Library there is a window on the right panel.

Meister DLL Wizard creates the head file of the output code of the DLL library, which looks exactly like the output code generated for the primary program. That one has the same responsibility. that this file begins with a reserved word library, but not program.

Library Project1; ( 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 export any procedures or functions that pass strings as parameters or applies to all strings passed to and from your DLL - even those that are nested in records and classes using BORLNDMM.DLL, pass string information using PChar or ShortString parameters (Project -> Show output code)), whichever your DLL exports. be it procedures or functions that pass rows as parameters or results of sequential functions. This includes all the rows that are transferred or maintained from your DLL, and links to the rows that are included in the records of that class. The ShareMem module is an interface module for the administrator of the shared memory BORLNDMM.DLL, which must be generated simultaneously from the DLL library. To avoid compromising BORLNDMM.DLL, add row information to the PChar or ShortString parameters. ) uses SysUtils, Classes; ($R *.res) begin end.

Everything you need to do at once is to add a subprogram before the block begin-end, from i everything. Then you select an internal subprogram that can be found in the DLL, but not in external programs. If you want to link the program from other programs or other DLLs, you need to export it. To export the subprogram to them, add them to the list exports. list exports has the same syntax as the list uses, just like what's on the list exports Whether any element is a subprogram or not a module.

list exports Please be placed right in front of the block begin-end. Take a look at Listing 1, which shows the output code for a simple library. FirstLib.dll, which exports one function.

Listing 1. A simple DLL

Library FirstLib; function Max3(Num1, Num2, Num3: Integer): Integer; stdcall; begin Result:= Num1; if Num2 > Result then Result:= Num2; if Num3 > Result then Result:= Num3; end; (Export function Max3) exports Max3; begin end.

If you add the subprogram to the list exports You will then export the program to their name. You can also export the subprogram under other names using additional directives name or for additional help of ordinal significance, Vikorist’s directive index. However, put the directive index not recommended.

Below is the example of the export directive using an additional ordinal value or under other names:

Exports Max3 name "MyMax3Function", SaySomething index 1;

Static import is the simplest of the two possible ways to import a DLL. Static attraction is also called dynamic connections under the hour of attraction ( load-time dynamic linking), because the selected DLLs are automatically installed when programs are launched.

To statically access a DLL, you need to copy the statements of the subprograms and add-ons that call, and assign them to additional directives. external, which informs the compiler that the subprogram is located either in an object file or in a DLL.

If you import routines from DLLs, you must label them with directives external, indicating behind it the name of the DLL library, which contains the implementation of subprograms. Below is an example of the import function MaxZ from the library FirstLib.dll:

Function Max3(Num1, Num2, Num3: Integer): Integer; stdcall; external "FirstLib.dll";

You can then rename the subprogram before importing. For which it is necessary to vote on the subprogram under other names, and finally vote on the initial names for additional directives name:

Function Max(Num1, Num2, Num3: Integer): Integer; stdcall; external "FirstLib.dll" name "Max3";

You can also import functions from DLLs. Why do you need to create an import module and write a standard subprogram header for the section? interface, and its external implementation - in the section implementation this module. Listing 2 readings have a new code for the library import module FirstLib.dll.

Listing 2. FirstLib.dll library import module.

Unit FirstLibInf; interface function Max3(Num1, Num2, Num3: Integer): Integer; stdcall; implementation const FirstLib = "FirstLib.dll"; (The compiler is informed that the implementation of the Max3 function is in the library FirstLib.dll) function Max3; external FirstLib; end.

After you create a DLL and an import module, flip the DLL over to the volume. that the subprogram is working normally. It is not possible to run the DLL itself; you need to create a test program that will access the DLL. The best way to make money is to create a project group by adding a new project to a full-scale project. For this you need to right-click on the element ProjectGroup1 at the window Project Manager(Project manager) and select the command in the context menu Add New Project,Yak is shown in Fig. 1.

Listing 3. Verification of Max3 subprograms that are imported from the FirstLib.dll library.

Unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, FirstLibInf, StdCtrls; type TMainForm = class(TForm) Edit1: TEdit; Edit2: TEdit; Edit3: TEdit; Label1: TLabel; Label2: TLabel; Label3: TLabel; Max3Button: TButton; procedure Max3ButtonClick(Sender: TObject); private (Private declarations) public (Public declarations) end; var MainForm: TMainForm; implementation ($R *.dfm) procedure TMainForm.Max3ButtonClick(Sender: TObject); var LargestNumber: Integer; begin LargestNumber:= Max3(StrToInt(Edit1.Text), StrToInt(Edit2.Text), StrToInt(Edit3.Text)); MessageDlg(Format("Highest: %d.", ), mtInformation, , 0); end; end.

Literature sourced: Inner World Borland Delphi 2006. Ivan Khladni.

More than once I had the opportunity to remove the sheets from the problem of creating and vikoristan DLL in Delphi. In this article, we will help you understand everything and create your own library. Dynamically linked libraries (Dynamic Link Library) give the ability to various add-ons when working to extract a hidden set of resources. It is important that the procedures and functions that are located in the DLL are completed in the middle of the process that is used to create them. The DLL provides for all add-ons one single copy of the resource, which is closely analyzed by all add-ons that have been requested, to be administrated as subprograms that run for each program that called them, its own copy. You can also enable subprograms where DLLs can export only procedures and functions, but not types, constants, etc.

I would like to take a lesson from “Lessons from Delphi” about the DLL structure of memory:

DLL is a library that is administrated by programs and does not require any stack or information. Functions placed in DLLs are placed in the context of the program that called on its stack. All these functions are used to create a segment of data that belongs to the library, and not a copy of the program. Due to this organization of DLLs, memory savings result from the fact that all running programs use one DLL module, without including any other standard functions in the storage of their modules. Often, DLLs are created around sets of functions, united by these and other logical signs, similar to the way modules (in the sense of unit) are conceptually planned in Pascal. The difference lies in the fact that functions from Pascal modules are linked statically, at the linking stage, and functions from DLLs are linked dynamically, at run-time.

Creation DLL

The DLL structure differs little from the basic structure of the Object Pascal module. The DLL begins with the words Library, followed by the name of the library. Functions and procedures such as DLLs assigned to other clients (exports) are reinstated after the exports directive.

For a skin procedure or function, you can specify a number following the Index directive. If the number is daily, the compiler will carry out automatic indexing. Instead of a procedure number, you can use unique names, as specified by the name directive. If no function name or number is specified, then Delphi accepts export to names that match the function name.

The library can also place the initialization code that will be entered when it is imported. It is located between begin and end. Axis structure DLL:

Library First_Dll; uses<используемые модули>; <объявления и описания функций>exports<экспортируемые функции> <описание процедур и функций>begin<инициализационная часть>end.

I will provide a description of the export functions in the exports section:

Exports Function1 index 2; Fucntion2 name "My_sqr"; Function3;

As you already guessed, these functions may not be used for export!

Wikoristannya DLL

A module that requires modification of procedures and functions from DLLs is guilty of vicorizing the external directive. There are two ways to create a DLL (dynamic and static). In the first case, the program that calls the function from the DLL knows the name of the library and the entry point into it at which it is transferred, but the library does not change. In another window, there is a trace in front of the selected DLL, so that the required library is empty, and there is a necessary subprogram.

You can import the program using its name and number. Searching subprograms for the number will appear faster, but not manually.

Below is an example of importing the function of our First_DLL, as seen in the application:

(import by specific names) Function ImportByName; external "First_DLL" name "My_sqr"; (Import by index) Function ImportByOrdinal; external "First_DLL" index 2; (import by original name) Function Function3; external "First_DLL";

We took a look at the static method of creating a DLL. However, in some situations it is not clear in advance how much the library itself will be needed, so we can quickly do this using a dynamic method:

Uses WinTypes, WinProcs, ...; type TMyProc = procedure; var Handle: THandle; MyImportProc: TMyProc; begin Handle:=LoadLibrary("FirstDLL"); if Handle>=32 then (<=32 - ошибка! } begin @MyImportProc:=GetProcAddress(Handle,"My_sqr"); if MyImportProc<>nil then ...... (here the function is removed in a vikory way) end; FreeLibrary(Handle); end;

But everything that is written here is not at all clear and I want real, complete applications. I started to get confused, since there were few applications in the articles, and only theory, so I recommend to your respect a simple example of a vikoristan DLL.

Click on the menu File -> New and select DLL. Save the finished template that will be created under the name Project1.dpr.

Below is the final code:

Library Project1; uses SysUtils,Classes; Function Function1(x,y:integer):integer; export; bgin result:=x+y; end; Function Function2(x,y:real):real; export; var t:real; begin t:=exp(y*ln(x)); result:=t; end; exports Function1 index 1, Function2 name "My_sqr"; begin end.

There are two functions here, one calculates the sum of two numbers and is exported by number, and the other calculates x at step y and is exported by name.

Now let's create a new project and save it from other projects, for example, DemoDLL. There are two buttons on the form, clicking on the first one will click on the first procedure, and clicking on the other will click on the other one. The axis of the new code for this demo project:

Unit demo; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private (Private declarations) public (Public declarations) end; var Form1: TForm1; implementation ($R *.DFM) function ImportSumm(x,y:integer):integer; external "Project1" index 1; //import by number function ImportSqr(x,y:real):real; external "Project1" name "My_sqr"; //import to name procedure TForm1.Button1Click(Sender: TObject); var t:real; begin //Discover how many there will be two in the third step t:=ImportSqr(2,3); Showmessage(FloatTostr(t)); end; procedure TForm1.Button2Click(Sender: TObject); var t:integer; begin //Discover how many will be 10+10 t:=ImportSumm(10,10); Showmessage(IntTostr(t)); end; end.

Delphi, MySQL programmer. Illuminated the place. Specialty: Information technology security software.

What is a DLL? At a minimum, most PC users know that they have more programs, which you should know about everything and read this article. In this article, I’ll try to get through all the junk food that DLL is running around.

Let's take a look at it ourselves:

  1. Once again, in the “Hello World” area, we will create our own DLL.
  2. Let's learn how to use the functions of this DLL from our programs.
  3. Let's begin to look at the functions that export a DLL song.
  4. Maybe, maybe not.

DLL creation process

Let's start with the simplest thing - write your own DLL so that you can only have one function, which is to display the "Hello World" notification.

  1. Launch Delphi (I'm using Delphi 6).
  2. Go to: File -> New ->Other

On the New Doors tab, click on the DLL Wizard object. A new project is starting. Save it, for example, with MyFirstDLL.

A clean module has something like this:

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

Now let's write one more function, like ShowMessage() from the Dialogs module. Now, before starting the procedure, let’s add the Dialogs module to the Uses section. What, approximately, can you see:

Library MyFirstDLL; uses Dialogs; procedure MyFirstFunc; stdcall; begin ShowMessage("Hello World"); end; exports MyFirstFunc; begin end.

As you know, there is nothing complicated here. Let me just say that you can call functions either by name or by index (number), for which you need to write like this:

Exports MyFirstFunc index 1;

If you don’t understand anything in this code, then still try to figure it out yourself. I think that there won’t be any problems... Ale yakscho scho, then forum! Let's see how you can now access the value (MyFirstFunc) function from other projects?

Vikoristannya function DLL

The first crumb is crushed, on the right behind the small one... How can we improve this function?

And, at a minimum, two ways of attraction:

  1. Static
  2. Dynamic

The other way is simpler, so that during the time of attraction we can follow what is expected, and we can manage all the benefits that arise during attraction. Ale, first for everything, I marvel at the first method:

Let's create a new project, drop one button on the form and write next to the OnClick button:

Procedure TForm1.Button1Click(Sender: TObject); begin MyProc(); end;

That's not all! In the implementation section of the project write:

Implementation procedure MyProc(); stdcall; external "MyFirstDLL.dll" name "MyFirstFunc";

Ready! Compile the project and press the button! As soon as your information was received, everything is ok!

Now let's look at the method of dynamic attraction. For this method, use the LoadLibrary() function, and finally, for visualization, use the FreeLibrary() function.

Marvel at the butt:

Procedure TForm1.Button1Click(Sender: TObject); type TMyFunc = procedure; var DLLInstance: THandle; MyFunc: TMyFunc; begin DLLInstance:= LoadLibrary(PChar("MyFirstDLL.dll")); if (DLLInstance = 0) then begin MessageDlg("Unable to entitle DLL", mtError, , 0); Exit; end; try @MyFunc:= GetProcAddress(DLLInstance, "MyFirstFunc"); if Assigned(@MyFunc) then MyFunc() else MessageDlg("The required procedure was not found!.", mtError, , 0); finally FreeLibrary(DLLInstance); end; end;

After successfully acquiring the DLL with the LoadLibrary() function, using GetProcAddress() we find out the address of our function, which is where we call our procedure from the DLL. Finally, of course, you need to create FreeLibrary(). It is important that all code after successful acquisition, before FreeLibrary(), I put in a try finally block. This is guaranteed by the FreeLibrary system, when it is in the middle of the try except block, the exception is not sent to the blame (Exception).

On the right is that the successful clicks LoadLibrary and FreeLibrary tend to be guys. I axis why. The system for the skin library, which is involved in the process, contains a healer, which increases by 1 when the skin successfully clicks LoadLibrary. Apparently, when FreeLibrary is deleted, it changes this value, and it becomes equal to zero, which means that this library is no longer needed for this process, and it can be safely deleted m'yati.

If the pairing rule is not followed, then it can be done either before the immediate recovery (if FreeLibrary is installed) of the library from memory, or before it is “stuck” there (if FreeLibrary is not installed).

With this rule, there is no need to worry about the possible contribution of LoadLibrary / FreeLibrary clicks.

Review of the song DLL functions

Now we can see how it is possible to extract all function names from PE format files, including DLLs. The structure of the PE format cannot be seen here, however, and the publication will be without explanation.

Now, create a new project, place it on the ListBox form, which will show the names of the functions.

Axis whole project:

Unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) lb: TListBox; procedure FormCreate(Sender: TObject); private (Private declarations) cmdline: String; ImageBase: DWord; DosHeader: PImageDosHeader; PeHeader: PImageNtHeaders; PExport: PImageExportDirectory; pname:PDWord; name: PChar; public (Public declarations) end; var Form1: TForm1; implementation ($R *.dfm) procedure TForm1.FormCreate(Sender: TObject); procedure FatalOsError; begin ShowMessage(SysErrorMessage(GetLastError())); Abort; end; Var i: Integer; begin try if (ParamCount() IMAGE_DOS_SIGNATURE) then FatalOsError; PEHeader:= PImageNtHeaders(DWord(ImageBase) + DWord(DosHeader^._lfanew)); if (PEHeader^.Signature IMAGE_NT_SIGNATURE) then FatalOsError; PExport:= PImageExportDirectory(ImageBase + DWord(PEHeader^.OptionalHeader.DataDirectory.VirtualAddress)); pname:= PDWord(ImageBase + DWord(PExport^.AddressOfNames)); For i:= 0 to PExport^. lb.Items.Add(name); inc(pname); end; finally FreeLibrary(ImageBase); end; except Application.ShowMainForm:= False; Application.Terminate; end; end; end.

If you want to get started with the code yourself and you can’t do it right now, then our forum will definitely help you, come on in!

We add our Viewer to all DLLs

We have a DLL with a function ready, and we have a look at the function. It was no longer possible to add functionality to the action for the handiness of further robots. Let's spend some money. The explorer can open any folder. Let's go to Service -> Folder Power... Go to the "File Types" tab. The list appears to be in DLL format. If there is no such thing, then we will emboss the “Create” button and write DLL in the “Extension” field. Printed OK. The type we know is DLL. You can see it and it’s stamped “Dodatkovo”. Next to “Create”, in the “Designs” field we write those that are displayed in the context menu, for example DLL Viewer. Through looking around we discover our program.

All is ready!

Now, when you right-click on a file in DLL format, the menu will have our DLL Viewer. We choose and marvel at all the functions!

That's all, thank you for your respect!

Abbreviation DLL means "a library that is dynamically linked." Dll in Delphi This is a file that contains the procedures and functions necessary for the operation of a computer program, with which the program connects at the logging stage.

It would seem that all the necessary subprograms could be described in the body of programs, for which it is necessary to create an additional dll file and meet him at the hour of death? Try for greater flexibility of the created program. Over the course of time, data processing algorithms may change. Since the processing procedures will be carried out by many programs, they will have to recompile and re-transmit the large file to the managers. It’s much easier to transfer a small dll file that will require a few procedures, and run it automatically.

In addition, the work of the dll library will not remain in the program on which it will be created. Therefore, we can entrust the creation of dlls for our programs to third-party developers, without thinking about our programming, which stinks. All this, initially, will greatly speed up the completion and transfer of the finished project to the managers

Creating a DLL Library

Create dll in Delphi It’s not difficult to open the additional module. Use the command File -> New -> -> Other... In the dialog box that appears, select the DLL Wisard icon. As a result, Delphi will create a DLL library project:

library Project1;

( 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 - parameters or result functions. 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 use BORLNDMM.DLL, pass string information
vikoryst PChar or ShortString parameters. )

uses
SysUtils
Classes;

($R *.res)

begin
end
.

Select a name for the new dll library and save it in a nearby folder by selecting the command File -> Save As... The father has 4 files, among which the dll file will not be included. Of course, these are just text files to describe the project. To create a library dll file, you need to compile the project. Follow the team Project -> Compile Project. As a result, a dll file will appear in our folder, with which the main program will be connected.

The library is still empty.

...the text is now in the editing stage...