Mig's HomePage
Personal page of Michal Mig Novotný

Writing DLL libraries under Linux
Writing winapps under Linux
Testing Windows applications under Linux
Using LoadLibrary() to load DLL libraries

If you want to write dynamically linked libraries (DLL) for Windows under Linux based operating systems you have to have mingw32 packages mingw32-runtime, mingw32-binutils and mingw32-gcc installed first. The binutils package is required for dlltool. After installing those packages you have to write the source code having the __declspec(dllexport) defined for functions you want to export from this DLL library.

Here's an example of such a source code file called testlib.c:

#include <stdio.h>

#ifdef BUILDING_DLL
#define DLLEXPORT __declspec(dllexport)
#else
#define DLLEXPORT __declspec(dllimport)
#endif

DLLEXPORT int testsquare(int a)
{
  return a * a;
}
Now when you have the source code you need to compile it for Windows systems using the mingw32 gcc. First we compile it with the following command:
i686-pc-mingw32-gcc -o testlib.dll -mdll testlib.c -Wl,--out-implib,libtestlib.a -DBUILDING_DLL
and then we have the library ready to be used. Alternatively you could use following two commands to generate the object file first and then later generate the binary from the object file using:
i686-pc-mingw32-gcc -c -o testlib.o testlib.c -DBUILDING_DLL
i686-pc-mingw32-gcc -o testlib.dll -mdll testlib.o -Wl,--out-implib,libtestlib.a
Please note presence of BUILDING_DLL define there which makes the source compile with __decl(dllexport) to export the library function to be publicly visible and therefore accessible from applications.

Now we should be having testlib.dll and libtestlib.a files generated which are both necessary to compile the application that will be using this library.


For writing Windows applications under Linux we need packages as written above, for using the DLLs in your applications you need the DLL library along with the library file *.a. This is an example how to write an application using the library we have created above in Writing DLL libraries under Linux article. Creating such an application is the same as writing standalone application that's using a shared library but you will most likely have to provide location using -L<location> directive to the compiler/linker to point the linker to the directory with the library and library file.

Here's an example of such a source code file called test.c:

#include <stdio.h>

int main(int argc, char *argv[])
{
        printf("TestSquare(5): %d\n", testsquare(5));
        return 0;
}
To compile this you have to use the following command:
i686-pc-mingw32-gcc -o test.exe test.c -ltestlib -L<location>
which would create the file test.exe that's using the testlib.dll library to compute testsquare value.


After you create both library and the application you should test it to confirm everything is working fine. Under Linux you should use either Wine to emulate or, if you have the Windows virtual machine, you could test it in the Windows VM. If you would like to use Wine you will need Wine packages (downloadable from winehq.org) and after installing it you can run the Windows application using:
wine ./test.exe

This example command assumes your Windows executable file is called test.exe and you should be having result like:
$ wine ./test.exe
TestSquare(5): 25
$
When the executable resides in the same directory like the required library. If the required library is not found you will see the error message like:

$ wine ./test.exe
err:module:import_dll Library testlib.dll (which is needed by L"Z:\\home\\{path}\\test.exe") not found
err:module:LdrInitializeThunk Main exe initialization for L"Z:\\home\\{path}\\test.exe" failed, status c0000135
$
This error message can be fixed by copying the library (here called testlib.dll) to the same directory. When you try to run the same application under Windows but you omit to include the library you will see th error message 1114 (saying An initialization routine of a dynamic library (DLL) failed.) or something similar to this.

If you don't know whether the library will be available or not and your application doesn't require it to it's proper functionality and the library is just adding some new features to your application, like when your library is just a plug-in module, you should consider using LoadLibrary() API function instead.


If you want to write Windows application that should be using some library you created but only when the library exists, i.e. to allow application to be run even without loading the library (like plug-in modules does), you should consider using the LoadLibrary() Windows API function. This is the basic WinAPI function present in kernel32.dll library of Windows operating systems. This tutorial will guide you how you could create such an application. You will need packages mentioned above and also you will need to include the windows header files to allow Windows system to access the standard Windows functions. Fortunately, emulating those calls with Wine is working fine so you don't have to test in Windows VM or anything else.

First of all, you need to include the windows.h and winbase.h header files to your application to be able to access WinAPI functions and then you should create a HMODULE handle to handle the library itself. The function to be loaded should be having it's typedef and the variable to be used should to carry the function pointer be defined at the beginning. Then your code should be having LoadLibrary(), GetProcAddress() and FreeLibrary() calls (in that order) with error checking whether the library and function could be found there or not etc. The code for ...

#include <windows.h>
#include <winbase.h>

int main() {
        HMODULE lib = NULL;
        typedef int (WINAPI *pTestSquare)(int);
        pTestSquare pTS = NULL;

        lib = LoadLibrary("testlib.dll");
        if (!lib) {
                printf("Cannot load specified library testlib.dll\n");
                return 1;
        }

        pTS = (pTestSquare) GetProcAddress(lib, "testsquare");
        if (pTS != NULL)
                printf("TestSquare(5): %d\n", pTS(5));
        else
                printf("TestSquare export not found in testlib.dll library\n");
        FreeLibrary(lib);
	return 0;
}
To compile this you have to use the following command:
i686-pc-mingw32-gcc -o test.exe test.c
This will create the test.exe executable file with no requirement for testlib.dll library. When you run this application but the library won't be available the error message that library cannot be found will be and application will return with error code 1.