Writing DLLs

I had some trouble with finding a good, quick (yet comprehensive) way to create and use dlls that didnt reference the Visual Studio IDE (I dont want to use it) and weren’t full of useless general knowledge information (a dynamic link library, or dll for short, is a…). So I went ahead and jotted down some notes after i got some things working.

Create the Dll

You start with some c code for your library:

$ cat libgreet.c

#include <stdio.h>
#include <windows.h>

BOOL DllMain(HINSTANCE hi, DWORD dw, LPVOID lp) {
        printf("oh hai ^-^\n");
        return 1;
}

void greet() {
        printf("Hello, World!\n");
}

The DllMain function is optional but will be called automatically called when the dll is loaded and freed.

You may compile this to a relocatable object file:

$ cl -c libgreet.c

This generates an .obj file which you can use along with a .def file:

$ cat libgreet.def

LIBRARY libgreet
EXPORTS
        greet

Alternatively, you can forgo a .def file and use __declspec(dllexport) in front of every function you want exported.

You can now link the dll with:

$ link -out:libgreet.dll -dll -debug -machine:x86  \
  libgreet.obj -def:libgreet.def

which should create the following files libgreet.dll, libgreet.lib (the static library to interface to the dll), libgreet.pdb (allows you to step through your library’s code in a debugger), libgreet.exp (?), and libgreet.ppp (???).

Using Your Dll

There are two ways to use the dll. The first is to use the static .lib file to interface to the dll. Heres an example:

$ cat use1.c

int main() {
        greet();
        return 0;
}

You may use the greet() function as though it will just be there (because it will). You may also declare the greet() function here or in a .h file that can be used by both this function and the original library code. Those declarations may have extern in front of them or not. Compile it with:

$ cl use1.c libgreet.lib

Which will produce a final .exe file.

The other way to load a dll at run time. This does not require any files other than the dll so long as you know the interface. You can get an idea of the exports available in a dll by doing:

$ dumpbin /exports libgreet.dll

Then you may write code like:

$cat use2.c

#include <stdio.h>
#include <windows.h>

int main() {
        HMODULE loaded_dll;
        FARPROC greet;

        printf("Hello, Erf!\n");

        loaded_dll = LoadLibrary("test.dll");
        if (loaded_dll == NULL) {
                printf("unable to load test.dll library\n");
                return 1;
        }

        greet = GetProcAddress(loaded_dll, "greet");
        if (greet == NULL) {
                printf("unable to obtain greet() from test.dll\n");
                return 1;
        }

        (*greet)();

        FreeLibrary(loaded_dll);

        return 0;
}

and compile like:

$ cl use2.c

About this entry