How to stop GNU GCC from mangling dll import function names

5

GNU GCC is mangling my imported function names even though I'm using extern "C" in the declarations.

I just started using Code::Blocks and GNU GCC for migrating existing projects off of Borland C++ Builder 6.0 Pro and developing some future projects. Long term, I will 1) be making .dlls that I want to be handing to end developers who are using a wide variety of platforms (i.e., the .dlls will not remain strictly in-house.) and 2) be making programs in Code::Blocks that use these .dlls.

When I tried to migrate the first project, which worked under Borland C++ Builder, it mangled the imported function names even when I declared them as 'extern "C".'

For example, the following (reduced) code produces errors after the compiler starts linking:

   #include <windows.h>

   #include <stdio.h>

   #include <cstdlib>

   #include "dsound.h"

   //#include "CGG_Cpp_DInterface.h"
   //The following are relevent items taken from CGG_Cpp_DInterface.h
   struct CrimsonReply1{
   unsigned int Echo;
   unsigned int Result;
   unsigned int ReplyType;
   unsigned int Reserved1;
   unsigned int Reserved2;
   char* OutputString;
   double Reply[32];
   };

   extern "C" __declspec(dllimport) int CrimsonCommandProc(/*I'm not going to list all the arguments here*/);
   extern "C" __declspec(dllimport) int TranslateCrimsonReply1(int, CrimsonReply1*, int);
   #define CGG_SETUP               0x20000001
   #define CGG_SHUTDOWN            0x20000005
   #define CGG_WINDOWED            0x0000002F
   #define CGG_RECTANGLE           0x00000024
   #define CGG_STRETCHTOCLIENT     0x00000028
   #define CGG_DUMPALLREPLIES      0
   //End of items taken from CGG_Cpp_DInterface.h
   extern "C" LRESULT CALLBACK WndProc(HWND hWnd, UINT messg, WPARAM wParam, LPARAM lParam );

   char szProgName[] = "Age Games:  Animal Reader";
   char message[] = "";
   extern "C"{

   int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPreInst, LPSTR lpszCmdLine, int nCmdShow)
   { //Win32 entry-point routine
     MSG WinEvent;//long pointer to an event message sent by Windows to the application
     WNDCLASSEX WinClass;//A Windows Class Struct
     RECT WindowRect;//A structure to describe the position and size of the window.
     HWND WinHand;

     /*Other Variables-------------------------------------------------------------*/
     CrimsonReply1 CrimsonReply;


     /*------------------------------------------------------------------------------
     Set up a window, register it, and create it.
     ------------------------------------------------------------------------------*/

     /*set up window class and register it*/
     /*All the standard window initialization is in here.  It's not relevent to the problem.*/
    /*------------------------------------------------------------------------------
    begin the message loop
    ------------------------------------------------------------------------------*/

    LPDIRECTSOUND* DirectSoundObject;
    HRESULT Result = DirectSoundCreate(NULL, DirectSoundObject, NULL);
    if (Result == DS_OK && *DirectSoundObject) Result = (*DirectSoundObject)->SetCooperativeLevel(WinHand, DSSCL_NORMAL);
    if (Result != DS_OK) return(0);
    int ReplyPointer = CrimsonCommandProc(CGG_SETUP,NULL,(double)(int)WinHand,NULL,CGG_WINDOWED,NULL,
                              CGG_RECTANGLE,NULL,800,NULL,600,NULL,
                              CGG_STRETCHTOCLIENT);
    if (ReplyPointer) ReplyPointer = TranslateCrimsonReply1(ReplyPointer, &CrimsonReply, CGG_DUMPALLREPLIES);

    while(GetMessage(&WinEvent, NULL, 0, 0))
    {
      DispatchMessage(&WinEvent);
    }
    /*------------------------------------------------------------------------------
    Shutdown.
    ------------------------------------------------------------------------------*/

    ReplyPointer = CrimsonCommandProc(CGG_SHUTDOWN);
    if (ReplyPointer) ReplyPointer = TranslateCrimsonReply1(ReplyPointer, &CrimsonReply, CGG_DUMPALLREPLIES);

    return(WinEvent.wParam);
  } //end of WinMain()

  }

This code produces the following errors:

  C:\Development\AnimalReader\Animal Reader.cpp|91|undefined reference to `DirectSoundCreate@12'|
  C:\Development\AnimalReader\Animal Reader.cpp|96|undefined reference to `_imp__CrimsonCommandProc'|
  C:\Development\AnimalReader\Animal Reader.cpp|97|undefined reference to `_imp__TranslateCrimsonReply1'|
  C:\Development\AnimalReader\Animal Reader.cpp|107|undefined reference to `_imp__CrimsonCommandProc'|
  C:\Development\AnimalReader\Animal Reader.cpp|108|undefined reference to `_imp__TranslateCrimsonReply1'|

Hence, it's mangling the DirectSoundCreate function name with the @12, even though I'm using microsoft's dsound.h file (which puts it inside an 'extern "C" ' block) and it's mangling CrimsonCommandProc with _imp__ even though I'm putting everything in the scope of 'extern "C".' How do I get GNU GCC Compiler to stop mangling the names? (Both for when it imports dll functions and eventually when it creates dlls)

Alternatively, I'm not married to GNU GCC. If there's another compiler that is A) Free, B) Cross-platform, and C) works with DirectX .lib files (preferrably something that will have support when new versions come out), I could use it.

c++
gcc
codeblocks
asked on Stack Overflow Jan 24, 2012 by user1167758

1 Answer

3

DirectSoundCreate is declared as WINAPI, a macro for __stdcall:

 extern HRESULT WINAPI DirectSoundCreate(...);

Which gives it the @12 decoration. You are probably getting the linker error because you are not linking dsound.lib. Or whatever version of you have is missing the export, not uncommon in the mingw version of the SDK files.

You are getting the __imp prefix because you declared the functions __declspec(dllimport). Just remove that.

answered on Stack Overflow Jan 24, 2012 by Hans Passant • edited Jan 24, 2012 by Hans Passant

User contributions licensed under CC BY-SA 3.0