0

I have a C header as follows:

Utilities.h:

extern SHM shm; //a struct.

extern void GetDesktopResolution(int* width, int* height);

extern bool CreateSharedMemory(uintptr_t id);

extern bool OpenSharedMemory(uintptr_t id);

extern bool UnMapSharedMemory();

and the implementation is a .c file that just implements the above functions:

SHM shm = {0};

bool CreateSharedMemory(uintptr_t id)
{
    //...
}

bool OpenSharedMemory(uintptr_t id)
{
    //...
}

bool UnMapSharedMemory()
{
    //...
}

This compiles perfectly fine.

Then I have a main.cpp file as follows:

#include "Utilities.h"


void swapBuffers(void* dsp, unsigned long wnd)
{
    if (!shm.mapped)
    {
        #if defined _WIN32 || defined _WIN64
        OpenSharedMemory((uintptr_t)dsp) || CreateSharedMemory((uintptr_t)dsp);
        #else
        OpenSharedMemory((uintptr_t)wnd) || CreateSharedMemory((uintptr_t)wnd);
        ftruncate(shm.hFile, shm.size);
        #endif // defined
    }
}
#endif // defined

When I compile it, I get:

obj\Release\src\main.o:main.cpp:(.text+0x249): undefined reference to `OpenSharedMemory(unsigned int)'

obj\Release\src\main.o:main.cpp:(.text+0x26c): undefined reference to `CreateSharedMemory(unsigned int)'

c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.8.1/../../../../x86_64-w64-mingw32/bin/ld.exe: obj\Release\src\main.o: bad reloc address 0x1 in section `.text.startup'

collect2.exe: error: ld returned 1 exit status

However, if I change "main.cpp" to "main.c" it compiles fine.. I checked and the .cpp file is compiled with g++ and the .c files are compiled with gcc but for some odd reason, the two object files cannot be linked together.

Any ideas what I'm doing wrong?

Brandon
  • 22,723
  • 11
  • 93
  • 186

1 Answers1

1

The Utilities.c file was/is probably compiled with C linkage, so the compiler does not perform name-mangling. As such, those functions are invisible for a C++ compiler.

In order to explicitly tell the compiler about a specific linkage of functions from given headers, wrap the include directive in *.cpp files with extern "C":

extern "C"
{
    #include "Utilities.h"
}

or create a separate header file (e.g. Utilities.hpp) with the following content:

extern "C" void GetDesktopResolution(int* width, int* height);

extern "C" bool CreateSharedMemory(uintptr_t id);

extern "C" bool OpenSharedMemory(uintptr_t id);

extern "C" bool UnMapSharedMemory();
Piotr Skotnicki
  • 46,953
  • 7
  • 118
  • 160