3

I have a C Project which uses a C++ library. However, if i compile the C Project i get a long list of "undefined reference to XY" errors.

Those errors are caused by C++ references:

Errors while compiling:

In function `<c function>':
implicit declaration of function `<function>'
[...]

(list shorted)
Where <c function> is the calling function from C Project and <function> the function from the C++ library.

Errors while linking:

undefined reference to `std::cerr'
undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
[...]
undefined reference to `__gxx_personality_v0'
more undefined references to `__gxx_personality_v0' follow

(lots of errors - example shorted)

In the static C++ library my types / functions are enclosed by extern "C" block:

#ifdef  __cplusplus
extern "C"
{
#endif

    void example();

#ifdef  __cplusplus
}
#endif

To ensure this, all the #include's referring to C++ library are surrounded by such a extern "C" block too.

Compiler: The C++ library is compiled using g++, the C project using gcc - both from MinGW.

CL (Linking): gcc -L<search-path here> -shared [...] -lstdc++ -l<C++ library set here>

Please note the -lstdc++ flag.

Note:

  • The C project contains only .c and .h files – no .cpp
  • Putting a "dummy" cpp file in like stated here didn't work
  • MinGW and Eclipse CDT Indigo
  • The C++ Library has a name like lib<NAME>.a - it's linked with -l<NAME>, search path is set.


Edit:

Using g++ as linker: undefined reference to std::cerr'` etc. are gone, but i get another list of errors:

Warning: .drectve `-aligncomm:"___hexdig_D2A",5' unrecognized
undefined reference to `<function / class / method from C++ Library>'
[...]
undefined reference to `_Unwind_Resume'
[...]
undefined reference to `__gxx_personality_v0'
more undefined references to `__gxx_personality_v0' follow
undefined reference to `__chkstk_ms'
[...]

(list shorted)

eg. _Unwind_Resume is available in nm of the c++ library.


Example:

This part is in the Library (C++):

Test.h - Header

#ifndef TEST_H_
#define TEST_H_

// --- Pure C++ here ---
#ifdef __cplusplus

#include <string>     /* (1) */
class Test
{
public:
    Test();
    
    
    void aMethod();
    
private:
    int i;
};
#endif

// --- Mixed (C / C++ ) here ---

#ifdef __cplusplus
extern "C"
{
#endif
   
    extern void doTest();
    extern void invoke();
    
#ifdef  __cplusplus
}
#endif

#endif /* TEST_H_ */

Test.cpp - Implementation of C++ part

#include "Test.h"


Test::Test() : i(0) { }

void Test::aMethod()
{
    this->i++;
}


void invoke()
{
    Test i;
    i.aMethod();
}

Test.c - Implementation of C Interface (still in library!)

#include "Test.h"

void doTest()
{
    invoke();
}

Now, here comes the part of the second project (pure C):

#include "Test.h"


int main(int argc, char* argv[])
{
    doTest();
    
    return 0;
}

(1): If i remove that include i can compile the C Project. But adding one include for any kind of class or c++ stuff causes lots of errors while linking. unfortunately i need to include classes etc..

Btw. here's the error i get for this example:

Test.cpp:(.text+0x1b): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string()'
Test.cpp:(.text+0x64): undefined reference to `_Unwind_Resume'
Test.cpp:(.text$_ZN4TestD1Ev[Test::~Test()]+0x12): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
Test.cpp:(.eh_frame+0x6b): undefined reference to `__gxx_personality_v0'

setting -lstdc++ flag after (!) the flag for the library i get "only" these:

Test.cpp:(.text+0x64): undefined reference to `_Unwind_Resume'
Test.cpp:(.eh_frame+0x6b): undefined reference to `__gxx_personality_v0'
Community
  • 1
  • 1
ollo
  • 24,797
  • 14
  • 106
  • 155
  • Those references at the end look like references to functions provided by the C++ runtime (not the standard library, but the actual runtime stuff). Try adding `-lc++` to the link command? (Actually, g++ should take care of that...but eh.) – cHao Mar 11 '13 at 13:36
  • Doesn't work: `ld.exe: cannot find -lc++`. – ollo Mar 11 '13 at 13:41
  • As a test i removed all calls of functions from library; without them i can compile without errors. unfortunately i need these function calls :-/ – ollo Mar 11 '13 at 14:37
  • 2
    If you have Test.cpp and Test.c, how do you create two different object files with different names? With files `main.c`, `test1.c` and `Test.cpp`, on Red Hat (RHEL 5, x86_64), compiling the files separately and linking with `g++ -o main main.o test1.o Test.o` works fine. – Jonathan Leffler Mar 11 '13 at 23:49
  • I tested one file for both too, same result. But if it works for you, i'll check my compiler. – ollo Mar 12 '13 at 08:42
  • Looks like a bug in gcc - using a newer version solved all errors from above. However it's not working because of another problem (but i guess thats another question). – ollo Mar 12 '13 at 08:54

2 Answers2

4

This problem looks like a bug in MinGW GCC.

  • Using GCC 3.4.5: Error as posted above
  • Using GCC 4.7.2: No Error

Also make sure -lstdc++ is the last (!) of your -l flags.

ollo
  • 24,797
  • 14
  • 106
  • 155
1

Link your project with g++ rather than gcc. G++ will take care of linking in the necessary c++ runtime implementation.

karunski
  • 3,980
  • 2
  • 17
  • 10
  • Using `g++` solves the reference to C++ std library problem, but i get a long list of errors too (please see my edit). – ollo Mar 11 '13 at 13:32