Подтвердить что ты не робот

С++ undefined ссылки со статической библиотекой

Я пытаюсь создать статическую библиотеку из класса, но, пытаясь ее использовать, я всегда получаю ошибки с ссылками undefined на что-либо. Способ, которым я продолжал, - создать объектный файл, например

g++ -c myClass.cpp -o myClass.o

а затем упаковывая его с помощью

ar rcs myClass.lib myClass.o

Есть что-то, чего я, очевидно, вообще не вижу в этом. Уверен, что-то с символами. Спасибо за любой совет, я знаю, что это, скорее всего, что-то, что я мог бы узнать, если бы прочитал какой-то учебник, так жаль, если снова потрудился с глупыми вещами:)

изменить

myClass.h:

class myClass{
    public:
        myClass();
        void function();
};

myClass.cpp:

#include "myClass.h"

myClass::myClass(){}
void myClass::function(){}

используя класс:

#include "myClass.h"

int main(){
myClass mc;
mc.function();

return 0;
}

Наконец, я скомпилирую его следующим образом:

g++ -o main.exe -L. -l myClass main.cpp

ошибка просто классическая:

C:\Users\RULERO~1\AppData\Local\Temp/ccwM3vLy.o:main.cpp:(.text+0x31): undefined
 reference to `myClass::myClass()'
C:\Users\RULERO~1\AppData\Local\Temp/ccwM3vLy.o:main.cpp:(.text+0x3c): undefined
 reference to `myClass::function()'
collect2: ld returned 1 exit status
4b9b3361

Ответ 1

Это, вероятно, проблема с порядком привязки. Когда GNU-компоновщик видит библиотеку, он отбрасывает все символы, которые ему не нужны. В этом случае ваша библиотека появляется перед вашим .cpp файлом, поэтому библиотека отбрасывается до компиляции файла .cpp. Сделайте это:

g++ -o main.exe main.cpp -L. -lmylib

или

g++ -o main.exe main.cpp myClass.lib

Линейщик Microsoft не учитывает упорядочение библиотек в командной строке.

Ответ 2

Другая возможная причина: забыть extern "C".

Я столкнулся с этим, потому что пытался связать программу на С++ с C статической библиотекой. У заголовка библиотеки не было extern "C", поэтому компоновщик искал искомое имя функции, а на самом деле библиотека имела непереписанное имя функции.

Понадобилось время, чтобы выяснить, что происходит, поэтому я надеюсь, что это поможет кому-то другому.

Ответ 3

Использование:

g++ -o main.exe main.cpp myClass.lib 

Использование пути библиотеки и флага -l чревато проблемами, но если вы это сделаете, переименуйте свою библиотеку в libmylib.a и затем скомпилируйте как:

g++ -o main.exe main.cpp -L. -lmylib 

Обратите также внимание на то, что по соображениям переносимости, как правило, плохая идея использовать смешанный регистр в именах исходных или выходных файлов.

Ответ 4

Это проблема, связанная с тем, как компоновщик оптимизирует выходной код. Предположим, у нас есть исполняемый файл, который использует две библиотеки: Lib_A и Lib_B. Lib_A зависит от Lib_B Lib_A определяет символы: Lib_A1 и Lib_A2, а Lib_B определяет символ Lib_B1 и Lib_B2. Теперь предположим, что исполняемый файл использует только символ Lib_A1, а Lib_A1 использует символ Lib_B1, который определен в Lib_B. Символ Lib_B1 никогда не используется в исполняемом файле.

  • В случае окон компоновщик работает следующим образом: у меня есть исполняемый файл с двумя, который использует некоторые библиотеки и все символы, используемые в исполняемом файле, и все библиотеки lib_A1 и lib_B1. Таким образом, мне понадобятся эти два символа, а остальное не нужно. Я определю lib_A2 и lib_B2
  • В случае linux, если вы связываете Lib_B до Lib_A следующим образом: g++ .... -lLib_B -lLib_A Компоновщик работает следующим образом: у меня есть исполняемый файл, который сначала соединяет Lib_B. Я не вижу, что исполняемый файл использует символ Lib_B1 или Lib_B2. Они носят ненужный характер, таким образом я буду их определять. Позже линкер видит. О, у меня есть другая библиотека Lib_A. Я вижу, что исполняемый файл использует символ Lib_B1. Я сохраню его и undefine неиспользованный символ Lib_B2. Он не видит, что Lib_B1 использует Lib_A1, который уже undefined.
  • В случае Linux, если вы связываете Lib_A до Lib_B следующим образом: g++ ... -lLib_A -lLib_B Компоновщик работает следующим образом: у меня есть исполняемый файл, который сначала соединяет Lib_A. О, я вижу, что исполняемый файл использует Lib_A1. Я сохраню их и определю Lib_A2. Позже это видно. О, у меня есть другая библиотека Lib_B. Я вижу, что теперь исполняемый файл с уже связанными символами, использует Lib_B1, я сохраню их. В результате он сохраняет Lib_B1 и Lib_A1 и undefined Lib_B2 и Lib_A2.

Ответ 5

Это должно избегать связывания ошибок и создания общей библиотеки .so.

LOCAL_ALLOW_UNDEFINED_SYMBOLS := true