Your First DLL

Delphi is one of the best IDEs, (Integrated Development Environment ex: like Game Maker), for creating Windows™ programs, including dynamic link libraries aka dlls. It is object-oriented, (note Game Maker does teach various aspects of object-oriented design ex: object.x=0) and has a Pascal language construct (again, Game Maker also teaches Pascal: if x=y then begin x=0; y=10; end;);). So the language shouldn’t look too much alien to us Game Maker users. Delphi compiles into assembly programs, making it fast and lightweight, unlike Game Maker which is interpreted. For those curious out there, Game Maker was built with Delphi.

Fortunately for us, there is a free and legal version available on the internet, which is Delphi 7 Personal (meaning it is for non-commercial projects). There are two problems with it though; the download size is a mighty 54Mb and Borland doesn’t advertise it anywhere, but secretly (well infamously) hosts it. Further information on obtaining your own registered version of Delphi could be found on Mario’s Valdez Blog, where a link to the Borland site with Delphi’s download is to be found. The installation and registration of Delphi is left up to the reader.

Looking at the first dll example in the history of Game Maker, we find the infamous example by Prof. Mark Overmars in the Game Maker manual, which is in Delphi. So we will start by using that sample code for our dll. But first let’s give a quick glance to the IDE.

There is a main menu which gives access to everything, some tabs with components (they work like GM’s D&D, except that they need to ‘Drawn’ on the forms), and some toolbar buttons to give quick access to typically used functionality. On the left side there two tool windows, the top one shows the object tree view, a hierarchical view of the components used and the object inspector, basically, a two column table with component’s attributes (aka properties) on the left and their values on the right.

Creating the Delphi DLL
To create a new Delphi dll project, run Delphi and click File->New->Other. A window should open displaying all available projects. Select the ‘DLL Wizard’ item and click ‘OK’.

Before we start with the code, we must understand how object-oriented works. There are several keywords you won’t find anywhere else; here are some of them:

Form – A Form is simply a window were you could put controls on.

Controls/Components/Objects – This is a sort of plug-in code which you could use and reuse, for example buttons, edit boxes, labels… Delphi is designed to work with objects, as such, nonvisible components exist. For example, popup menus are still viewed as a small button like the other controls.

Property – This is a sort of control’s attribute, for example it’s left position, ‘Left’, in Game Maker it would be object0.x.

Method – This is new for Game Maker users, methods are functions/procedures executed by a particular object, for example:

RichEdit1.Lines.LoadFromFile(‘text.rtf’);.

As you see, only RichEdit1 will load rtf data from the rtf file (lines is a property showing the rich edit box’s data organized in an array), the actual method here is LoadFromFile. Basically there are two types of methods:

Procedures – These are blocks of code that could not return values.

Functions – These blocks of code must return a value.

In the editor (the central window) you will find some code created by the dll wizard. Delphi’s code editor colorhighlights your code in Pascal (it has support for 8 languages: c/c++, c#, default, HTML, IDL, Pascal, SQL and XML).

It is a bit limited, but I find it to my liking. The editor shows reserved words in bold. The first such word is ‘library’ this shows to Delphi that the project is about a dll. The next word is what the dll will be named.

In order to make my explanation more clear, save the project as MinMaxEx. This will automatically change the second word in the project code, which is the project’s name.

Important: Delphi does a lot of automatic code generation and manipulation, for example as we saw, the project name changed automatically when it was saved.

Now let’s look at the Delphi code. First thing we notice is that unlike GM, Delphi, uses ‘{’ and ‘}’ for multi-line comments (GM uses ‘/*’ and ‘*/’). Single line comments still work like GM’s ‘//’. Ignore the warning in the comments; we use PChar not Strings, so just remove the comments to gain some more space. Next, there is the Uses keyword, after this, you define a list of what units you are going to use, just like c/c++’s header system. Each unit is used for a particular purpose, for example, for mathematics, system utilities, forms…

We need to add ‘Math,’ after SysUtils (note the comma after Math); this is because Min and Max are found in this unit. Note that sometimes units are added automatically, and that you could create your own. The next text is {$R *.res}. This is a compiler directive, that is, when the program is going to be compiled, the compiler does something special. In this case, it is specifying a resource file $R=resource switch, *.res=use all .res files. Resource files contain information like the program icon, version info… It is managed automatically by Delphi and is considered poor practice to change manually as Delphi continually updates it. Next, there is ‘begin…end.’.

The code is executed when the dll is loaded, and usually we dll makers don’t use it, all code after the final period is ignored by the compiler, this applies to every code file. So let’s create our first dll function, add the following code before ‘begin…end.’:

function MinEx(arg0,arg1,arg2,arg3:double):double; begin Result:=Min(Min(arg0,arg1),Min(arg2,arg3)); end;

The first line of code has this structure: function : ;

‘name’ is the function’s name; make sure it doesn’t clash with other functions.

‘args’ is a list of variable names that will receive the argument’s value.

‘arg type’ is declaration that tells what the variables’ type is.

‘result type’ tells what is the function’s result type.

First we note the variable type ‘double’, this is exactly what GM’s variables types are. Double is larger then a normal integer. The best two variable types used in dlls for GM are Doubles (for numbers) and PChars (for text). ‘Result’ is a variable created only in functions, which is used to contain the function’s result.

Note: the code flow doesn’t end when ‘result’ is used (unlike GM’s return).

Min function is declared in the Math unit, and takes only two arguments, so for four arguments, we use two Min functions for two arguments and another Min for the results.

Lastly, we need to make the function public to the dll’s users, thus we need to export the function. This is done by using the exports keyword, so add the following code after the function code:

exports MinEx;

Implementing MaxEx is left as an exercise to the reader. Hint: When using multiple function names in exports, use a comma inbetween them. Here is a collection of all resulting code so far (without MaxEx hehe):

library MinMaxEx; uses SysUtils, Math, Classes; {$R *.res} function MinEx(arg0,arg1,arg2,arg3:double):double; begin Result:=Min(Min(arg0,arg1),Min(arg2,arg3)); end; exports MinEx; begin end.

Now let's look at the Game Maker side; as you see, we didn’t say anywhere what the dll call type is (stdcall or cdecl), so Delphi defaults to stdcall (which by the way is a standard call). So here is our GML initialization code:

// Initialize MinMaxEx dll global._MME0='MinMaxEx.dll' global._MME1=external_define(global._MME0,'MinEx',1,   ty_real,4,ty_real,ty_real,ty_real,ty_real)

And MinEx script:

// MinEx(1,2,3,4)=1 return external_call(global._MME1,argument0,argument1,   argument2,argument3);