Search code examples
cgccdlldeclspec

Trying to compile simple dll written in C using gcc fails


Trying to compile a simple DLL written in C using gcc.

Tried following many tutorials, but can't get it to compile even when I strip the file down to the very basics.

test_dll.c

#include <stdio.h>

__declspec(dllexport) int __stdcall hello() {
    printf ("Hello World!\n");
}

Trying to compile this using the command

gcc -c test_dll.c

Failing, getting this output

test_dll.c: In function '__declspec':
test_dll.c:3:37: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'hello'
 __declspec(dllexport) int __stdcall hello() {
                                     ^
test_dll.c:5:1: error: expected '{' at end of input
 }
 ^

gcc version

gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)

Solution

  • It depends on what you're trying to do:

    1. build a library for linux on linux

    then remove the __declspec(dllexport) and __stdcall. On linux, you need nothing special in the source code for building a library. Note that libraries aren't DLLs on linux, they're named *.so (shared object). You'll have to compile with -fPIC and link with -shared to create your .so file. Please use google for more details on this.

    2. build a windows DLL on linux

    Install mingw packages (search for them in your package manager). Then, instead of just gcc, invoke the cross compiler targeting windows/mingw, e.g. i686-w64-mingw32-gcc.

    3. allow to build libraries cross-platform, including windows

    If you want to be able to build a library from the same code on windows and linux, you'll need some preprocessor magic for this, so __declespec() is only used when targeting windows. I normally use something like this:

    #undef my___cdecl
    #undef SOEXPORT
    #undef SOLOCAL
    #undef DECLEXPORT
    
    #ifdef __cplusplus
    #  define my___cdecl extern "C"
    #else
    #  define my___cdecl
    #endif
    
    #ifndef __GNUC__
    #  define __attribute__(x)
    #endif
    
    #ifdef _WIN32
    #  define SOEXPORT my___cdecl __declspec(dllexport)
    #  define SOLOCAL
    #else
    #  define DECLEXPORT my___cdecl
    #  if __GNUC__ >= 4
    #    define SOEXPORT my___cdecl __attribute__((visibility("default")))
    #    define SOLOCAL __attribute__((visibility("hidden")))
    #  else
    #    define SOEXPORT my___cdecl
    #    define SOLOCAL
    #  endif
    #endif
    
    #ifdef _WIN32
    #  undef DECLEXPORT
    #  ifdef BUILDING_MYLIB
    #    define DECLEXPORT __declspec(dllexport)
    #  else
    #    ifdef MYLIB_STATIC
    #      define DECLEXPORT my___cdecl
    #    else
    #      define DECLEXPORT my___cdecl __declspec(dllimport)
    #    endif
    #  endif
    #endif
    

    Then put a DECLEXPORT in front of each declaration to be exported by the lib and SOEXPORT in front of each definition. That's just a quick example.