Advanced Features of Delphi DLLs

Source: Internet
Author: User

Http://www.delphisources.ru/pages/faq/master-delphi-7/content/LiB0104.html

Beside this introductory example, you can do a few extra things with the dynamic libraries in Delphi. You can use some new compiler directives to affect the name of the library, you can call a DLL at run time, and you can pl Ace entire Delphi forms inside a dynamic library. These is the topics of the following sections.

Changing Project and Library Names

for a library, as for a standard application, your end up with a library name matching a Delphi proje CT filename. Following a technique similar to, introduced in Kylix for compatibility with standard Linux naming conventions for Sha Red object Libraries (the Linux equivalent of Windows DLLs), Delphi 6 introduced special compiler directives you can use I n libraries to determine their executable filename. Some of these directives make + sense in the Linux world than on Windows, but they ' ve all been added anyway:

  • $LIBPREFIX is used to add something in front of the library name. Paralleling the Linux technique of adding Lib in front of the library names, this directive was used by Kylix to add C2>BPL at the beginning for package names. It is necessary because Linux uses a single extension (. So) for libraries, whereas in Windows can has different library extensions, something Borland uses for packages (. BPL).

  • $LIBSUFFIX is used to add text after the library name and before the extension. This text can is used to specify versioning information or other variations on the library name and can is quite useful on Windows.

  • $LIBVERSION is used to add a version number after the extension-something very common in Linux, and that's you should genera Lly avoid on Windows.

These directives can is set in the IDE from the application page of the Project Options dialog box, as can see in Figu Re 10.3. As an example, consider the following directives, which generate a library calledMarcoNameTest60.dll:

Library nametest; {$LIBPREFIX ' Marco '} {$LIBSUFFIX '"}

Figure 10.3:the Application page of the Project Options dialog box now have a Library Name section. Delphi 6 Packages introduced the extensive use of the $LIBSUFFIX directive. For this reason, the VCL package now generates the VCL.DCP file and the vcl70.bpl file. The advantage of this approach is so you won ' t need to change the requires portions of your packages for every New version of Delphi. Of course, this is helpful if you move projects from Delphi 6 to Delphi 7, because past versions of Delphi didn ' t provid E this feature. When your reopen Delphi 5 packages you still has to upgrade their source code, an operation the Delphi IDE does Automatica Lly for youCalling a DLL Function at Run time

Referenced in your code the functions exported by the libraries, so the DLLs were loaded Program. I mentioned earlier that you can also delay the loading of a DLL until the moment it's needed so you can use the rest of The program in case the DLL is not available.

Dynamic loading of a DLL in Windows are accomplished by calling the LoadLibrary API function, which searches for the DL L in the program folder, the folders on the path, and the some system folders.  If The DLL is not found, Windows would show an error message, something you can skip by calling Delphi ' ssafeloadlibrary function. This function had the same effect as the API it encapsulates, but it suppresses the standard Windows error message and SHO Uld be the preferred-to-load libraries dynamically in Delphi.

If the library is found and loaded (something you know by checking the return value of LoadLibrary orSafeloadlibra RY), a program can call the GetProcAddress API function, which searches the DLL's exports table, looking for the name Of the function passed as a parameter. If GetProcAddress finds a match, it returns a pointer to the requested procedure. Now, can cast this function pointer to the proper data type and call it.

Whichever loading functions you ' ve used, don ' t forget-call FreeLibrary at the end, so the the DLL can be properly Released from memory. In fact, the system uses a reference-counting technique for libraries, releasing them if each loading request have been F Ollowed by a freeing request.

The example I ' ve built to show dynamic DLLs loading is named Dynacall. It uses the Firstdll library built earlier in this chapter (for the program work that you had to copy the DLLs from their so Urce folder into the folder as the Dynacall example). Instead of declaring the Double and Triple functions and using them directly, this example obtains the same effect With somewhat more complex code. The advantage, however, is and the program would run even without the DLL. Also, if new compatible functions is added to the DLL, you won ' t has to revise the program ' s source code and RE Compile it to access those new functions. Here are the core code of the program:

typetintfunction=function(I:integer): Integer;stdcall; ConstDllName='Firstdll.dll'; procedureTform1.button1click (sender:tobject);varHinst:thandle;  Fpointer:tfarproc; myfunct:tintfunction;beginHInst:=safeloadlibrary (DllName); ifHInst >0  Then  TryFpointer:=GetProcAddress (HInst, PChar (Edit1.text)); ifFpointer <>Nil  Then    beginmyfunct:=tintfunction (Fpointer); Spinedit1.value:=myfunct (Spinedit1.value); End    ElseShowMessage (Edit1.text+'DLL function not found'); finallyFreeLibrary (HInst); End  ElseShowmes

As the library uses the Borland memory manager, the program dynamically loading it must do the same. Need to add the SHAREMEM unit in the project of the Dynacall example. Oddly enough, this is not so with past versions of Delphi, in case the library didn ' t effectively use strings. Be warned so if you omit this inclusion, you'll get a harsh system error, which can even stall the debugger on the F Reelirbary call.

How does call a procedure in Delphi, once are you having a pointer to it? One solution is to convert the pointer to a procedural type and then call the procedure using the Procedural-type variable , as in the previous listing. Notice The procedural type you define must is compatible with the definition of the procedure in the DLL. This was the Achilles ' heel of this method-there is no actual check of the parameter types.

what is the advantage of this approach? In theory, you can use it to access any of the function of any DLLs at any time. In practice, it was useful when you had different DLLs with compatible functions or a single DLL with several compatible F Unctions, as in the case. You can call The double and triple methods by entering Their names in the edit box. Now, if someone gives your a DLL with a new function receiving an integer as a parameter and returning an integer, can Call it by entering its name in the edit box. You don ' t even need to recompile the application.

With this code, the compiler and the linker ignore the existence of the DLL. When the program is loaded, the DLL was not loaded immediately. You might make the program even more flexible and let the user enter the name of the DLL into use. In some cases, the is a great advantage. A program could switch DLLs at run time and something the direct approach does not allow. Note that this approach to loading DLL functions are common in macro languages and are used by many visual programming EnviR Onments.

Only a system based on a compiler and a linker, such as Delphi, can use the direct approach, which are generally more relia Ble and also a little faster. In my opinion, the indirect loading approach of the Dynacall example are useful only in special cases, but it can be extrem Ely powerful. On the other hand, I see a lot of value with using dynamic loading for packages including forms, as you'll see toward the EN D of this chapter.

Placing Delphi Forms in a Library

Besides writing a library with functions and procedures, where can place a complete form built with Delphi to a dynamic Li Brary. This can is a dialog box or any of the other kind of form, and it can is used not only by other Delphi programs, but also by othe R development Environments or macro languages with the ability to use dynamic link libraries. Once you ' ve created a new library project, all of need to does is add one or more forms to the project and then write Expor Ted functions that would create and use those forms.

For example, a function activating a modal dialog box to select a color could is written like this:

functionGetColor (col:longint): Longint;cdecl;varFormscroll:tformscroll;begin//defaultvalue Result:=Col; TryFormscroll:=tformscroll.create (application); Try//Initialize the data formscroll.selectedcolor:=Col; //Show the formifFormscroll.showmodal = Mrok ThenResult:=Formscroll.selectedcolor; finallyFormscroll.free; End; exceptOn e:exception DoMessagedlg ('Error in library:'+ E.message, Mterror, [Mbok],0); End;End;

What makes this different from the code you generally write in a program was the use of the exception handling:

  • A&NBSP; try/  block protects the whole function.
    Any exception generated by the function would be trapped, and a appropriate message would be displayed.
    You handle every possible exception because the calling application might is written in any language-
    in particular , one that doesn ' t know what to handle exceptions.
    Even when the caller was a Delphi program, it was sometimes helpful to use the same protective approach.

  • A try/finally Block protects the operations on the form,
    Ensuring that the form object would be properly destroyed even if an exception is raised.

By checking the return value of the ShowModal method, the program determines the result of the function.

I ' ve set the default value before entering the try block to ensure that it 'll always be executed

(and also to avoid the compiler warning indicating, the result of the function might be undefined).

You can find this code snippet in the Formdll and Usecol projects, available in the Formdll folder.

(There ' s also a wordcall. TXT file showing the routine from a Word macro.).

The example also shows that's can add a modeless form to the DLL, but doing so causes far too much trouble.

The modeless form and the main form is not synchronized,

Because the DLL has its own global Application object in its own copy of the VCL.

This situation can is partially fixed by copying the Handle of the application ' s Application object

To the Handle of the library ' s Application object.

Not all of the problems is solved with the code this can find in the example.

A better solution might is to compile the program and the library to use Delphi packages,

So, the VCL code and data won ' t be duplicated.

But this approach still causes a few troubles:

It's generally advised that you don't use Delphi DLLs and packages together.

So what's the best suggestion I can give?

For making the forms of a library available to other DELPHI programs, use packages instead of plain dlls!

Advanced Features of Delphi DLLs

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.