Невозможно вызвать код 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