Невозможно вызвать код C++ из C без ошибок

Я пытаюсь написать библиотеку C++, которую можно вызвать из C. Однако всякий раз, когда я пытаюсь написать хотя бы минимальный пример, он вылетает с неопределенными ссылками. Вот мой код:


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;
}

Процесс компиляции происходит примерно так:

g++ -c mylibrary.cpp -o mylibrary.o (создать "mylibrary.o")

ar rcs libmylibrary.a mylibrary.o (создать статическую библиотеку "libmylibrary.a")

gcc main.c -L. -lmylibrary (свяжите статическую библиотеку и скомпилируйте исходный файл C)

Тем не менее, я получаю этот дамп ошибки:

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

Любые предложения о том, как устранить ошибку?

2 ответа

Решение

mylibrary.o все еще зависит от стандартной библиотеки C++ и gcc не знает об этом. Вызов gcc с -lstdc++ на последнем этапе.

Создание динамической библиотеки вместо статической библиотеки должно помочь:

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

а потом:

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

с:

$ 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
Другие вопросы по тегам