2016-12-21 4 views
0

Я собрал библиотеку с g++, и я хочу связать ее с gcc.
Проблема я получаю ошибку при линковании против него:Как удалить окружающие символы вокруг символа в общей библиотеке?

неопределенная ссылка на «functionName`

(FunctionName это имя функции в библиотеке)

хотя функции существует в списке символов, и я указываю путь к gcc при связывании.

Это происходит потому, что функция появится в списке с окружающими символами (я думаю, что это для подмены?):

Z12functionNameiSt9__va_list

Я знаю, что для удаления этих символов я должен окружать объявление функции с extern "C" , И я сделал это:

//header.hpp 
extern "C" int functionName(int argc, ...); 

Но окружающие символы по-прежнему появляются вокруг имени функции в списке символов. И вот почему gcc не может его найти.

я кросс компиляции для Linux руки yokto с arm-poky-linux-gnueabi-gcc и arm-poky-linux-gnueabi-g++ на Ubuntu Desktop 16.

Почему не окружающие символы удаляются, и как я могу удалить их? Я никогда не буду переопределять эту функцию, поэтому, если они действительно предназначены для переопределения, мне они не нужны.


редактировать:

решаемая. Подпись функции в ее декларации отличалась от подписи в ее определении ... Поэтому ключевое слово extern было ни за что.

int functionName(int argc, ...); //declaration 
int functionName(int argc, va_list args) //definition 
+0

Возможно, вы забыли '#include ' –

+0

@BasileStarynkevitch - Включено –

ответ

1

Этими персонажами называют mangling. Они кодируют сигнатуру функции, поэтому перегрузка C++ может работать правильно (например, int foo(int) и int foo(float) - это разные символы).

Если ваш API - C, вам необходимо исправить библиотеку, чтобы не было привязки. Постройте его как C или добавьте extern "C" в свой код. Если ваш API должен быть C++, удалите extern "C" из своего заголовка.

Если искаженные имена не совпадают (различное манипулирование), то у вас, вероятно, есть проблема совместимости с ABI. В этом случае попытка устранить проблему с каналом - неправильное решение. Вам нужно убедиться, что вы создаете свой код с тем же ABI, что и библиотека.

Инструмент c++filt должен иметь возможность декодировать искаженный символ в подпись. Это может быть полезно, чтобы выяснить, в чем разница.

Учитывая вы построили библиотеку с g++ и пытаются связать с gcc, то, скорее всего вы хотите C API и восстановление библиотеки с extern "C" на месте, что вам нужно.

+0

API - это c (без классов), но функция использует библиотеки C++. Я добавил 'extern 'C" 'в заголовок (см. Сообщение), но не удаляет окружающие символы. Может быть, потому, что сигнатура функции имеет многоточие ('...')? –

+0

@AlaaM. Нет, он отлично работает с многоточием. Вы перестроили библиотеку с помощью «extern» C «present»? Я понял из вашего сообщения, что компоновщик ищет 'functionName', но библиотека содержит' Z12functionNameiSt9__va_list', что означает, что проблема связана с библиотекой. Также убедитесь, что библиотека фактически включает заголовок, а не просто определяет функцию без каких-либо 'extern 'C". – Olivier

+0

Как я уже сказал в сообщении, я знаю, что проблема в библиотеке. Проблема в том, что он все еще содержит окружающие символы –

0

«Окружающие символы» на самом деле предназначены для name mangling. Так лучше говорить о искаженные имена.

Вы, вероятно, следует добавить

#ifdef __cplusplus 
extern "C" { 
#endif 

вблизи начала файла (общественного) заголовка (что вы будете лучше код в общем подмножестве C и C++), а также соответствие

#ifdef __cplusplus 
}; // end of extern "C" 
#endif 

возле его конца. См. Также this.

Вы должны обернуть все свои общедоступные заголовки (и, возможно, стандартные C заголовки, включенные им), с такими вещами (а не только с отдельными функциями).

Вы можете скомпилировать с gcc -H, чтобы перечислить включенные заголовки или g++ -C -E, чтобы получить предварительно обработанную форму (и изучить ее).

+0

Я не понимаю, как это отличается от того, что я упомянул? Я уже добавил 'extern 'C" '. –

Смежные вопросы