3

I'm trying to write a C++ library that can be called from C. However, whenever I try to even write a bare minimum example, it crashes with undefined references. Here is my code:


mylibrary.h

#ifndef __MY_CPP_THING_H
#define __MY_CPP_THING_H

#ifdef __cplusplus
extern "C" {
#endif

void printSomething();

#ifdef __cplusplus
}
#endif

#endif

mylibrary.cpp

#include <iostream>

#include "mylibrary.h"

extern "C" {

void printSomething() {
    std::cout << "PLEASE PRINT\n";
}

}

main.c

#include "mylibrary.h"

int main() {
    printSomething();
    return 0;
}

The compiling process goes something like this:

g++ -c mylibrary.cpp -o mylibrary.o (create "mylibrary.o")

ar rcs libmylibrary.a mylibrary.o (create static library "libmylibrary.a")

gcc main.c -L. -lmylibrary (link static library and compile C source file)

However, I receive this error dump:

mylibrary.o:mylibrary.cpp:(.text+0x17): 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*)'
mylibrary.o:mylibrary.cpp:(.text+0x32): undefined reference to `std::ios_base::Init::~Init()'
mylibrary.o:mylibrary.cpp:(.text+0x62): undefined reference to `std::ios_base::Init::Init()'
mylibrary.o:mylibrary.cpp:(.rdata$.refptr._ZSt4cout[.refptr._ZSt4cout]+0x0): undefined reference to `std::cout'
collect2.exe: error: ld returned 1 exit status

Any suggestions on how to resolve the error?

11
  • 6
    The front-end program gcc doesn't link with the C++ standard library. You either have to do it yourself or use g++ when linking as well. And yes, g++ can be used to compile and build C source file as well, just as gcc can compile C++ source files. I know there are duplicates to this. Commented Sep 14, 2018 at 8:06
  • Basically don't call C++ from C. C++ library functions will, for instance, use exceptions and the C calling code cannot cope with them. Commented Sep 14, 2018 at 8:07
  • @Someprogrammerdude Unfortunately, due to my circumstances,gcc is the only option I have. How would I go about linking the standard library? Commented Sep 14, 2018 at 8:10
  • @pmg There are plenty of decent ways to deal with that. The OP is not doing any of them, but that is beside the point. Commented Sep 14, 2018 at 8:10
  • @Griffort Does your cpp lib have to be a static lib? Commented Sep 14, 2018 at 8:11

2 Answers 2

7

mylibrary.o still depends on C++ standard library and gcc doesn't know about it. Call gcc with -lstdc++ in the last step.

Sign up to request clarification or add additional context in comments.

1 Comment

Another alternative is to use g++ for your linker step
3

Creating a dynamic library instead of a static library should do the trick :

$ gcc -c main.c
$ g++ -fPIC -shared -o mylibrary.so mylibrary.cpp
$ gcc -o main main.o mylibrary.so

and then :

$ LD_LIBRARY_PATH=".:${LD_LIBRARY_PATH}" ./main
PLEASE PRINT

with :

$ objdump -p main | grep NEEDED
  NEEDED               mylibrary.so
  NEEDED               libc.so.6
$ objdump -p mylibrary.so | grep NEEDED
  NEEDED               libstdc++.so.6
  NEEDED               libc.so.6

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.