|
I believe that Delphi is the best
development for creating DLLs. Delphi makes the whole process relatively
painless and gives full flexibility. Instead of talking about it, lets
dive right in and let’s look at what it takes to build a DLL.
Sample DLL
To create a sample DLL go to Delphi’s
File|New and select DLL. This will give you a sample DLL skeleton that
looks like this:
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
View-Project
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
DELPHIMM.DLL shared memory manager, which must be deployed along
with
your DLL. To avoid using DELPHIMM.DLL, pass string information
using
PChar or ShortString parameters. }
uses
SysUtils,
Classes;
begin
end.
This will compile into a DLL called
Project1 but in fact it doesn’t do anything at all. Lets add a ‘HelloWorld’
procedure.
Hello?
Just after the uses clause add this:
procedure
HelloWorld; stdcall; export;
begin
MessageBox(0,'Hello World.', 'From DLL', MB_OK);
end;
This HelloWorld procedure just displays
a simple messagebox with and OK button. First off, the keyword stdcall
tells the compiler the calling convention to be used for this procedure.
Calling conventions are beyond the scope of this article. Lets just say
that the stdcall calling convention is the standard way that functions
in Windows are called and leave it at that. The next keyword tells Delphi
that we want to export this procedure so that it can be called from another
process.
Save the project (File|Save Project
as) as SampleDLL and compile it. (Project|Compile or Ctrl+F9). You now
have a DLL called SampleDLL.DLL that has one exported function called HelloWorld.
Now this HelloWorld procedure can
be called from any windows program that knows about it. When I say "knows
about it" I mean that it knows that there is a procedure called HelloWorld
in the SampleDLL.DLL. There are two ways to call a procedure in a DLL.
One is implicit linking and the other is called explicit linking.
Implicit Linking
This means that the function that
you want to call is hard coded into the program and that windows will do
all the dirty work of finding the DLL and Loading it at runtime. This is
the easiest way to import function and procedures from a DLL but also means
your program won’t run if it can’t find the DLL or the procedure you want
to import.
Now that you saved and compiled the
DLL lets create a simple program to call the HelloWorld procedure.
Create a new application (File|New
Application) and Drop a button on the form. Double Click the button and
add code into the event handler so it looks like this:
procedure
TForm1.Button1Click(Sender: TObject);
begin
HelloWorld;
end;
Gee, that was simple. But there is
one more small thing you have to do. Remember, I said the program had to
know about the procedure HelloWorld. Well you tell it by declaring an import
statement. Go to the implementation section and type this line.
procedure
HelloWorld; external 'SampleDLL.dll';
This tells the compiler that you
want to import and external procedure called HelloWorld and that it can
be found in a DLL called SampleDLL. That’s it!
Explicit Linking
This means that you are going to
take care of all the messy details in locating the DLL and calling the
procedure yourself. This is a bit more work but the code is straightforward.
The benefits of this are that you don’t have to bomb out if the DLL can’t
be found. You could exit gracefully or call some sort of default. Ok on
to the code. Add another Button to your form and add the following code
so that it looks like this:
procedure
TForm1.Button2Click(Sender: TObject);
var
hMod : THandle;
HelloWorld : procedure;
begin
hMod := LoadLibrary('SampleDLL.DLL');
if (hMod = 0) then Exit;
@HelloWorld := GetProcAddress(hMod, 'HelloWorld');
if @HelloWorld <> nil then HelloWorld;
FreeLibrary(hMod);
end;
This Loads the DLL and locates the
address for the procedure. If it was found then it is called. Then the
DLL is freed. This gives you a lot more flexibility but it does require
some more code. You would probably add some default behavior if the procedure
was not found.
Your sample
program
If you now compile and run your sample
program you will see a form with two buttons on it. Pressing either one
will both produce the same result - A small message box that says HelloWorld.
Things not
covered
There are a number of things I did
not cover in this short tutorial. There is a DLLEntryPoint procedure that
windows expects to see in all DLLs. There is one in your sample you don’t
see because it was created for you. You can define your own but that is
only really required when you want to be notified when the DLL is first
attached and detached from the calling process and when threads are created
and terminated.
The DLL you made can be called from
a C program or C++ program as long as the calling convention is the same.
That is why I suggest always using stdcall.
Also you can make DLLs that hold
resources such as bitmaps, AVIs, strings, etc.
Conclusion
I hope that this tutorial has enlightened
you a little. If you never used Delphi before I’m sure it was an eye opener.
It really didn’t take much to create a sample DLL with a HelloWorld procedure
and the two ways of calling it were fairly simple. There were a few things
that I didn’t cover but really are more advanced topics that you can find
out more about when the need arises.
- Posted by Fatty,
written by Robert Kozak
[an error occurred while processing this directive]
|