#c #gcc #multiple-definition-error
#c #gcc #ошибка множественного определения
Вопрос:
У меня есть рабочая библиотека C, которую я хочу связать с приложением на C с помощью gcc, но компоновщик (g ) выдает мне ошибку «множественное определение». С приложением на C и gcc это работает. Все заголовки, определяющие интерфейс, содержат:
#ifdef __cplusplus
extern "C" {
#endif
Я проверил библиотеку с помощью команды «nm», и в ней действительно есть несколько определений метода (рассматриваемый метод не из общедоступного интерфейса).
Мои вопросы:
-
Почему моя библиотека имеет несколько определений (у некоторых есть T, а у других — U)?
-
Почему это работает, если приложение, включающее файл, является приложением на C (я использую -Wall для сборки)?
-
Нужен ли мне какой-либо специальный атрибут или использовать определенное расширение файла, чтобы это работало, или мне нужно вернуться в школу программирования :)?
Уделяя больше внимания файлу lib.a, я вижу, что один из объектов включен дважды. Например, у меня есть два раздела для одного и того же объекта:
obj1.o
00000000 T Method
obj2.o
00000000 T Hello
obj1.o
00000000 T Method
Я предполагаю, что это проблема?
Любая помощь действительно ценится.
Комментарии:
1. Для наглядности. Являются ли множественные символы общедоступным интерфейсом библиотеки (т. Е. Тем, что находится в файлах заголовков) или из стандартного содержимого библиотеки?
2. Вы создаете со всеми одинаковыми настройками? Несколько настроек приведут к несовместимости двоичных файлов — т. Е. соглашения о вызовах по умолчанию и тому подобное.
3. Для Laserallan — хороший вопрос. Повторяющиеся символы взяты из стандартной библиотеки.
4. Для Билли Онеала — Да, те же настройки, просто используются -I и -L, ничего особенного.
5.Где вы используете
gcc
и / илиg
при создании приложения на C ? Предположим, у вас есть исходные файлыcLib.c
cApp.c
иcppApp.cpp
. Если вы попробуете это, я полагаю, это сработает?gcc cLib.c -o cLib.o; gcc cApp.c -o cApp.o; gcc cLib.o cApp.o -o cApp.exe
Но это не удается?:gcc cLib.c -o cLib.o; g cppApp.cpp -o cppApp.o; g cLib.o cppApp.o -o cppApp.exe
Ответ №1:
Мое дикое предположение заключается в том, что «#define BLAHBLAH_H» и «#ifndef BLAHBLAH_H / #endif» устанавливаются за пределами ‘extern «C»{}’.
Комментарии:
1. Слишком дико 🙂 методы, о которых идет речь, не являются общедоступными, поэтому их заголовки не нуждаются во внешнем C. (по крайней мере, насколько я знаю).
2. Я не очень хорошо разбираюсь в cpp. Однако в C ключевое слово extern просто означает, что переменная / функция объявлена где-то и, следовательно, она объявляется локально без указания фактического определения. Если больше ничего не работает, возможно, стоит попробовать. 😛 Я с нетерпением жду реальной причины и решения.
Ответ №2:
поиграв, я обнаружил, что фактически вся командная строка (это своего рода сложное приложение с автоматической компиляцией и компоновкой) содержала параметр —whole-archive перед включением библиотеки C. Перемещение библиотеки после —no-whole-archive устранило проблему.
Исходная команда
gcc -Wl,**--whole-archive** -l:otherlibs *-Llibpath -l:libname* Wl,**--no-whole-archive** -o myApp hello.c
Исправлена команда
gcc -Wl,**--whole-archive** -l:otherlibs Wl,**--no-whole-archive** *-Llibpath -l:libname* -o myApp hello.c
Спасибо всем за помощь, ребята, и извините, если я не предоставил достаточной / точной информации.
С наилучшими пожеланиями