Search code examples
cwindowsintrospectionname-manglingdlopen

Prevent name mangling in C (not C++) with MinGW for dynamic symbol search


I have a C program where I get function pointers "dynamically" by the function name (ie. I pass the function name as a string and get a pointer to the function). I already do this in Linux using dlopen and dlsym and I suppose it will also work in any other Unix-like with dlfcn.

The problems began when I tried to port this program to Windows using MinGW. When I try to find the name using "GetProcAddress(handle, symbol_name), where "symbol_name" is the name of my callback function and "handle" is a handle to the current executable returned by "GetModuleHandle(NULL)", I get nothing because the MinGW name mangling adds an "_" to my symbol name.

The obvious solution (prefix an "_" to the symbol I want) seems a bit 'dangerous' for portability (may the compiler add two underscores for some of them? I don't know), so, I ask:

  • There is a better way to prevent the compiler from name-mangling my symbols? (or a subset of them, only the callbacks I need to find dynamically);

  • Or a way to make GetProcAddress find them even when mangled?

I also tried the option -fno-leading-underscore, but it removed the mangling of all the external symbols too, making the program impossible to link with the stdlib, etc. (also, the warnings on the documentation are a bit scary).

Also, please note that I'm using pure C -- there is no C++ in any part of my code -- and all my code lives in a single ".exe".

TIA


Solution

  • Not sure what your problem is, as I can't reproduce it with the simplest DLL example I can think of:

    /* hello_dll.c */
    #include <stdio.h>
    
    __declspec(dllexport) void hello ( void )
    {
        puts ( "Hello, DLL!");
    }
    
    /* hello_exe.c */
    #include <windows.h>
    #include <stdio.h>  
    
    int main () {
        typedef void (*pfunc)(void);
    
        HANDLE hself;
    
        pfunc hello;
    
        hself = GetModuleHandle(NULL);
    
        hello = (pfunc)GetProcAddress(hdll, "hello");
    
        hello();
    
        return 0;
    }
    

    This is the command line using MinGW gcc with no special flags, and it all works:

    gcc src\hello_dll.c src\hello_exe.c -o bin\hello.exe
    $ bin\hello.exe
    Hello, DLL!
    $ gcc --version
    gcc (GCC) 4.5.0
    

    It doesn't work without the __declspec(dllexport) if you are getting the function from yourself; when creating a DLL with gcc -shared it doesn't appear to be necessary, but appears to be required if exporting a function from an exe.