Tuesday, August 3, 2010

Cross-Compiling DLLs with Linux

When working with a Linux-driven work environment, it is nice to be able to also compile your Windows projects under Linux. One question that arises is how to compile DLLs. Thankfully this is very straighforward process using MinGW.

Creating the DLL

Simply create a file example_dll.c with the fitting header example_dll.h
#include "example_dll.h"

int example_function(int n) {
return n*42;
}

#ifndef EXAMPLE_DLL_H__
#define EXAMPLE_DLL_H__

int example_function(int n);

#endif

Then just compile it with:
$> i586-mingw32msvc-gcc -shared example_dll.c -o example.dll

and viola, you have your DLL ready to use. This is just a simple example DLL, but with this method it is possible to create full-blown DLLs with thousands of lines of code. When you keep your code clean and platform-independet you can compile the same code into a shared library for Linux and a DLL for Windows and even link against other dynamic libraries like OpenSSL or libcurl, though it is advisable to use GNU Automake and GNU Libtool when creating larger projects to ease the hassle of the growing command lines, especially because of different options for Windows and Linux. GNU Automake will take care of all that automatically, also when cross-compiling.

Using the DLL

Using the DLL is just as you would expect it. In this example just create a file use_dll.c with following content:

#include <stdio.h>
#include "example_dll.h"

int main() {
int res = example_function(13);
printf("%d should be %d!\n", res, 13*42);

return 0;
}

Then your program compiles as simple as this, ready to use on any Windows system:
$> i586-mingw32msvc-gcc use_dll.c example.dll -o example.exe

Using GNU Automake

Creating DLLs with GNU Automake and GNU Libtool isn't difficult either. With your working Automake setup, simply add the macro
AC_LIBTOOL_WIN32_DLL
to your configure.ac and GNU Libtool will create clean DLLs for your project when configured for cross-compiling.

Using the DLL with MSVC

To link the DLL against a project in MSVC you will have to generate a .lib file, and for that you will have to generate a .def file. So when compiling on your Linux machine just add the following parameter to your gcc comandline:
-Wl,--output-def,example.def
which will tell the linker to output the .def file as example.def. Then on your Windows machine with a installation of some kind of MSVC compiler execute following command:
lib /machine:i386 /def:example.def
to compile the .def into a .lib which you can then link against in your project. Don't forget to do this step every time your API changes...

Author: Jonathan Dimond

No comments:

Post a Comment