Cannot Call C++ Code from C without Error

211 views Asked by At

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?

2

There are 2 answers

1
Ivan Todorović On BEST ANSWER

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

0
Sander De Dycker On

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