Почему я не могу связать смешанную статическую библиотеку C / C ++, которая имеет интерфейс C, используя gcc? - PullRequest
4 голосов
/ 13 сентября 2011

У меня есть смешанная библиотека C / C ++.

Снаружи она предоставляет интерфейс C с использованием внешнего языка C. Внутри есть шаблоны и классы.Создание библиотеки с помощью «ar» не представляло проблем.Файл называется libo-client.a.

Однако при связывании файла .a с использованием gcc (не g ++) я получаю множество ошибок, которые выглядят следующим образом:

libo-client.a(mysocket.o):(.rodata._ZTV7mStream[vtable for mStream]+0x10): undefined reference to `__cxa_pure_virtual'
...
mysocket.cpp:(.text+0x15ad): undefined reference to `operator new[](unsigned long)'
mysocket.cpp:(.text+0x15c1): undefined reference to `operator delete(void*)'
mysocket.cpp:(.text+0x167a): undefined reference to `__cxa_allocate_exception'
mysocket.cpp:(.text+0x16a6): undefined reference to `__cxa_throw'
...

Моя строка компиляции / ссылки выглядит следующим образом:

gcc $(CFLAGS) $(INCLUDES) test2.c libo-client.a -o test2 

Где test2 - мой тестовый комплект.

Эта проблема не возникает, когда я использую g ++.Однако я собираюсь связать эту библиотеку с проектом C, который скомпилирован с помощью gcc.Как мне обойти это?В чем причина?

РЕДАКТИРОВАТЬ:

Несмотря на то, что я не использую стандартную библиотеку C ++, очевидно, что нужны некоторые вещи, такие как оператор new / delete и т. Д., Иесть внутренние исключения.

Я связываю эту штуку с гипервизором Xen, поэтому я не уверен, какие у меня есть варианты, но полностью переписать эту штуку или, возможно, попробовать вместо этого скомпилировать Xen с G ++?

Ответы [ 5 ]

9 голосов
/ 13 сентября 2011

Самый простой способ обойти вашу проблему - это связать с g++; это дает правильные библиотеки на месте.

Проблема в том, что C ++ предъявляет множество требований, которых нет у C, и выполняет большую работу перед вызовом main(), чтобы гарантировать правильную инициализацию.

Если вы настаиваете на связывании с компилятором C, по крайней мере, вам нужно включить библиотеку поддержки C ++ в команду link.

2 голосов
/ 13 сентября 2011

Ваша библиотека C ++ по-прежнему является внутренней библиотекой C ++, что означает, что она содержит внешние ссылки на различные служебные функции из стандартной библиотеки C ++. Чтобы разрешить эти ссылки, вам нужно будет связать ваш окончательный исполняемый файл для стандартной библиотеки C ++. gcc не делает это автоматически. Либо явным образом предоставьте стандартную библиотеку C ++ для gcc, либо используйте вместо этого компилятор g++.

1 голос
/ 13 сентября 2011

Кажется, что вы видите ошибки из-за отсутствия связи со стандартной библиотекой C ++, в которой есть определение символа для оператора new, удаления оператора и т. Д. Попробуйте связать stdc++ скажем gcc $(CFLAGS) $(INCLUDES) test2.c libo-client.a -o test2 -lstdc++.Лучший вариант, как предлагает Джонатан Леффлер, использовать g++ вместо gcc

1 голос
/ 13 сентября 2011

Архив по-прежнему представляет собой просто набор объектных файлов (.o), поэтому при связывании их с исполняемой или общей библиотекой вам все равно нужно связать с g++, чтобы разрешить символы в среде выполнения C ++ (например, как только вы смотрите в ваших сообщениях об ошибках).

Чтобы ваши функции C имели C-linkage, этого должно быть достаточно, чтобы обернуть их в extern "C" блоки. Вещи могут быть более сложными, например, Windows, с ее множеством макросов связывания (STDCALL, WINAPI и т. Д.), Которые расширяются до других вещей (некоторых специфичных для компилятора), таких как __stdcall, __declspec (экспорт) и т. Д.

0 голосов
/ 30 января 2013

Написание материала на C ++, который можно использовать из C без каких-либо дополнительных возможностей, необходимых для C ++, очень трудный . Возможно, даже зависит от компилятора. Вашей библиотеке требуется среда выполнения C ++, а для инициализации среды выполнения C ++ требуется специальная поддержка перед вызовом main () в вашей программе. Ваша химера все еще в программе на C ++, когда вы связываете файлы C, даже если это main () и все остальное за пределами вашей библиотеки.

...