A dynamically loadable library is a dynamic-link library (DLL) on Win32, and an assembly (also a DLL) on the .NET platform. It is a collection of routines that can be called by applications and by other DLLs or shared objects. Like units, dynamically loadable libraries contain sharable code or resources. But this type of library is a separately compiled executable that is linked at runtime to the programs that use it.
Delphi programs can call DLLs and assemblies written in other languages, and applications written in other languages can call DLLs or assemblies written in Delphi.
You can call operating system routines directly, but they are not linked to your application until runtime. This means that the library need not be present when you compile your program. It also means that there is no compile-time validation of attempts to import a routine.
Before you can call routines defined in DLL or assembly, you must import them. This can be done in two ways: by declaring an external procedure or function, or by direct calls to the operating system. Whichever method you use, the routines are not linked to your application until runtime.
The Delphi language does not support importing of variables from DLLs or assemblies.
The simplest way to import a procedure or function is to declare it using the external directive. For example,
procedure DoSomething; external 'MYLIB.DLL';
If you include this declaration in a program, MYLIB.DLL is loaded once, when the program starts. Throughout execution of the program, the identifier DoSomething always refers to the same entry point in the same shared library.
Declarations of imported routines can be placed directly in the program or unit where they are called. To simplify maintenance, however, you can collect external declarations into a separate "import unit" that also contains any constants and types required for interfacing with the library. Other modules that use the import unit can call any routines declared in it.
You can access routines in a library through direct calls to Win32 APIs, including LoadLibrary, FreeLibrary, and GetProcAddress. These functions are declared in Windows.pas. on Linux, they are implemented for compatibility in SysUtils.pas; the actual Linux OS routines are dlopen, dlclose, and dlsym (all declared in libc; see the man pages for more information). In this case, use procedural-type variables to reference the imported routines.
uses Windows, ...; type TTimeRec = record Second: Integer; Minute: Integer; Hour: Integer; end; TGetTime = procedure(var Time: TTimeRec); THandle = Integer; var Time: TTimeRec; Handle: THandle; GetTime: TGetTime; . . . begin Handle := LoadLibrary('libraryname'); if Handle <> 0 then begin @GetTime := GetProcAddress(Handle, 'GetTime'); if @GetTime <> nil then begin GetTime(Time); with Time do WriteLn('The time is ', Hour, ':', Minute, ':', Second); end; FreeLibrary(Handle); end; end;
When you import routines this way, the library is not loaded until the code containing the call to LoadLibrary executes. The library is later unloaded by the call to FreeLibrary. This allows you to conserve memory and to run your program even when some of the libraries it uses are not present.
Copyright(C) 2008 CodeGear(TM). All Rights Reserved.
What do you think about this topic? Send feedback!