• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

C++ i biblioteki mysql

Object Storage Arubacloud
0 głosów
371 wizyt
pytanie zadane 30 kwietnia 2017 w C i C++ przez muchomor Nowicjusz (210 p.)
Witam
po wydaniu polecenia: g++ my_test.cpp
wywala mi takie błędy:




/tmp/ccBT620U.o: In function `main':
my_test.cpp:(.text+0x1c): undefined reference to `mysql_init'
my_test.cpp:(.text+0x54): undefined reference to `mysql_real_connect'
my_test.cpp:(.text+0x88): undefined reference to `mysql_errno'
my_test.cpp:(.text+0x98): undefined reference to `mysql_error'
my_test.cpp:(.text+0xb8): undefined reference to `mysql_close'
collect2: error: ld returned 1 exit status

 

Zawartość pliku my_test.cpp:

#include <stdio.h>
#include <mysql/mysql.h>
#include <iostream>



int main(int argc, const char * argv[])
{
    MYSQL mysql;

    mysql_init(&mysql); // incjalizacja
    
    if(mysql_real_connect(&mysql, "127.0.0.1", "baza", "", "baza", 0, NULL, 0))
        printf("Połączenie z bazą danych MySQL nawiązano poprawnie!\n");
    else
        printf("Błąd połączenia z bazą MySQL: %d, %s\n", mysql_errno(&mysql), mysql_error(&mysql));
    
    mysql_close(&mysql); // zamknij połączenie
    
    return 0;
}

Dodam, że biblioteka odpowiednia jest zainstalowana i ścieżka poprawnie podana(przynajmniej tak mi się wydaje, sprawdzałem podając celowo złą). Czy kompilator nie odnajduje metod czy źle kompiluję?

Zawartości biblioteki <mysql.h> nie wkleję bo zajmuje zbyt dużo miejsca

 

2 odpowiedzi

+2 głosów
odpowiedź 30 kwietnia 2017 przez mokrowski Mędrzec (155,460 p.)

collect2: error: ld returned 1 exit status

Co oznacza że linker zgłosił błąd braku włączenia biblioteki. Wywołanie kompilatora powinno wyglądać jakoś tak (o ile Twoja biblioteka nazywa się libmysqlpp.so.3:

g++ -lmysqlpp -o my_test my_test.cpp

 

komentarz 30 kwietnia 2017 przez adrian17 Ekspert (344,860 p.)
edycja 30 kwietnia 2017 przez adrian17
W tym przypadku `-lmysqlclient` (które, BTW, powinno być po liście plików .cpp), bo mimo że autor pytania zainstalował dodatkowe biblioteki dla C++a, korzysta z interfejsu dla C :)
komentarz 30 kwietnia 2017 przez muchomor Nowicjusz (210 p.)

Czułem właśnie, że to problem z linkerem ale nie wiedziałem jak się za to zabrać.

Dzięki wielkie za naprowadzenie, ale w dalszym ciągu nie wiem dlaczego tak trzeba kompilować skoro załączam całkiem inny plik w programie? Ktoś mógłby udzielić info?

Z góry dziękuję i pozdrawiam

Problem w moim przypadku rozwiązała opcja :

g++  -lmysqlclient -o my_test my_test.cpp

 

komentarz 30 kwietnia 2017 przez adrian17 Ekspert (344,860 p.)

dlaczego tak trzeba kompilować skoro załączam całkiem inny plik w programie?

Nie rozumiałem pytania :/ Ale jak rozjaśnisz to pewnie odpowiem.

komentarz 30 kwietnia 2017 przez muchomor Nowicjusz (210 p.)
Chodzi mi o wpis: #include <mysql.h> a podczas kompilacji linkujemy -lmysqlclient.

Nie rozumiem tych zależności i dlaczego akurat tak?
komentarz 30 kwietnia 2017 przez adrian17 Ekspert (344,860 p.)

(z uproszczeniami)

Tak naprawdę wywołanie

g++ my_test.cpp -lmysqlclient

(podobnie jak każde przejście .cpp -> plik wykonywalny) za kulisami wywołuje dwa programy.

  • kompilator kompiluje pliki .cpp/.c do plików pośrednich (.o). Do tego potrzebuje deklaracje funkcji z innych bibliotek. Dostaje je czytając nagłówki przez `#include`. Jeśli użyłeś mysql_init, w (tymczasowym) pliku my_test.o pojawi się notka "tu użyto funkcję mysql_init".
  • linker łączy pliki .o i pliki bibliotek (.so, .a) do postaci docelowej - w Twoim przypadku do wykonywalnego programu. Żeby łączyć, musi wiedzieć co łączyć. Skąd -lmysqlclient, które w tym przypadku jest skrótem na "dolinkuj plik /usr/lib/x86_64-linux-gnu/libmysqlclient.so".
komentarz 30 kwietnia 2017 przez muchomor Nowicjusz (210 p.)
Czyli zasada jest podobna jak w przypadku kompilowania głownego pliku.cpp + dodatkowe pliki z funkcjami.cpp ?

Teraz jest wszystko jasne. Dzięki
komentarz 30 kwietnia 2017 przez mokrowski Mędrzec (155,460 p.)

W uzupełnieniu:

https://pl.wikipedia.org/wiki/Dynamiczne_linkowanie

 Dodatkowo spróbuj wywołać w systemie GNU/Linux polecenie ldd. Tu dla przykładu dla programu ls:

$ ldd /usr/bin/ls
	linux-vdso.so.1 (0x00007fff9dbf1000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fa373ac5000)
	libcap.so.2 => /lib64/libcap.so.2 (0x00007fa3738c0000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fa3734fa000)
	libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fa373287000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fa373083000)
	/lib64/ld-linux-x86-64.so.2 (0x000055cb2d1f0000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fa372e63000)

Jak widzisz program /usr/bin/ls w systemie, korzysta z bibliotek dynamicznych, tak więc pewnie był kompilowany z "jakimiś przełącznikami -l" (minus el) :-) 

Dla biblioteki libpcap.so.2 będzie to -lpcap , dla libpcre.so.1 będzie to -lpcre . Utrącasz numer wersji oraz przedrostek lib.

0 głosów
odpowiedź 30 kwietnia 2017 przez QizmoPL Stary wyjadacz (11,440 p.)
komentarz 30 kwietnia 2017 przez muchomor Nowicjusz (210 p.)
Problem opisany wyżej dotyczy Windowsa i CodeBlocksa. Nie bardzo wiem jak rozwiązać mój. Dodam też, że wiem na czym polega ostrzeżenie: " undefined reference to".

Nie wiem jak to rozwiązać u mnie, podejrzewam, że g++ coś zawala albo sama biblioteka.

pakiety zainstalowane w systemie:

libmysql++-dev , libmysql++3, libmysqlclient-dev
komentarz 30 kwietnia 2017 przez QizmoPL Stary wyjadacz (11,440 p.)
nigdzie ine ma jawnie napisane z czego korzystasz, jak nie to, to nie mam inneg pomyslu

Podobne pytania

0 głosów
1 odpowiedź 510 wizyt
0 głosów
3 odpowiedzi 174 wizyt
0 głosów
1 odpowiedź 116 wizyt
pytanie zadane 17 lutego 2019 w SQL, bazy danych przez Mateusz Kacprzak Początkujący (360 p.)

92,572 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...