Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++][sqlite3] Aplikacja okienkowa Windows undefined reference to `sqlite3_open'

Ostatnio zmodyfikowano 2017-01-08 02:23
Autor Wiadomość
Leyla
Temat założony przez niniejszego użytkownika
[C++][sqlite3] Aplikacja okienkowa Windows undefined reference to `sqlite3_open'
» 2017-01-07 22:22:46
Informacje:
IDE: Dev C++ 5.11
Język: C++
Zależności: WinAPI, sqlite3

Dzień dobry

Mam problem ze skompilowaniem aplikacji, która korzysta z biblioteki sqlite3.h. Otrzymuję błąd:
A:\Programowanie\C++\test\main.cpp In function 'void database()':
25 9 A:\Programowanie\C++\test\main.cpp [Warning] deprecated conversion from string constant to 'char*' [-Wwrite-strings]
A:\Programowanie\C++\test\main.o main.cpp:(.text+0x87): undefined reference to `sqlite3_open'
A:\Programowanie\C++\test\main.o main.cpp:(.text+0xba): undefined reference to `sqlite3_exec'
A:\Programowanie\C++\test\main.o main.cpp:(.text+0xc5): undefined reference to `sqlite3_close'
A:\Programowanie\C++\test\collect2.exe [Error] ld returned 1 exit status
26 A:\Programowanie\C++\test\Makefile.win recipe for target 'Projekt2.exe' failed

Kod programu:
C/C++
#include <windows.h>
#include <sqlite3.h>
#include <string>

using namespace std;
string temp;

static int callback( void * firstArg, int argc, char ** argv, char ** colName ) {
    int i;
    temp = "";
    for( i = 0; i < argc; i++ ) {
        temp += argv[ i ];
    }
    temp += "\n";
    return 0;
}

void database() {
    sqlite3 * db;
    char * zErrMsg = 0;
    int rc;
    char * sql;
   
    rc = sqlite3_open( "BookBase51.db", & db );
    sql = "SELECT Title from book where Title like '%chiwum%'";
    sqlite3_exec( db, sql, callback, 0, & zErrMsg );
    sqlite3_close( db );
}

class Book {
protected:
    string title;
   
public:
    Book();
    string getDetails();
};

Book::Book() {
}

string Book::getDetails() {
    database();
    title = temp;
    return title;
}

/* This is where all the input to the window goes to */
LRESULT CALLBACK WndProc( HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam ) {
    switch( Message ) {
       
        /* Upon destruction, tell the main thread to stop */
    case WM_DESTROY: {
            PostQuitMessage( 0 );
            break;
        }
       
        /* All other messages (a lot of them) are processed using default procedures */
        default:
        return DefWindowProc( hwnd, Message, wParam, lParam );
    }
    return 0;
}

/* The 'main' function of Win32 GUI programs: this is where execution starts */
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) {
    WNDCLASSEX wc; /* A properties struct of our window */
    HWND hwnd; /* A 'HANDLE', hence the H, or a pointer to our window */
    MSG msg; /* A temporary location for all messages */
   
    /* zero out the struct and set the stuff we want to modify */
    memset( & wc, 0, sizeof( wc ) );
    wc.cbSize = sizeof( WNDCLASSEX );
    wc.lpfnWndProc = WndProc; /* This is where we will send messages to */
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
   
    /* White, COLOR_WINDOW is just a #define for a system color, try Ctrl+Clicking it */
    wc.hbrBackground =( HBRUSH )( COLOR_WINDOW + 1 );
    wc.lpszClassName = "WindowClass";
    wc.hIcon = LoadIcon( NULL, "A" ); /* Load a standard icon */
    wc.hIconSm = LoadIcon( NULL, "A" ); /* use the name "A" to use the project icon */
   
    if( !RegisterClassEx( & wc ) ) {
        MessageBox( NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK );
        return 0;
    }
   
    hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, "WindowClass", "Caption", WS_VISIBLE | WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, /* x */
    CW_USEDEFAULT, /* y */
    640, /* width */
    480, /* height */
    NULL, NULL, hInstance, NULL );
   
    if( hwnd == NULL ) {
        MessageBox( NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK );
        return 0;
    }
   
    /*
    This is the heart of our program where all input is processed and
    sent to WndProc. Note that GetMessage blocks code flow until it receives something, so
    this loop will not produce unreasonably high CPU usage
    */
   
    Book * bok = new Book();
    LPCSTR tekst = bok->getDetails().c_str();
   
    HWND hStatic = CreateWindowEx( 0, "STATIC", NULL, WS_CHILD | WS_VISIBLE, 50, 50, 150, 1200, hwnd, NULL, hInstance, NULL );
    SetWindowText( hStatic, tekst );
   
    while( GetMessage( & msg, NULL, 0, 0 ) > 0 ) { /* If no error is received... */
        TranslateMessage( & msg ); /* Translate key codes to chars if present */
        DispatchMessage( & msg ); /* Send it to WndProc */
    }
    return msg.wParam;
}

Gdy próbuję skorzystać z tej samej bazy w aplikacji konsolowej (tworzonej w Dev C++ jako "Plik źródłowy" a nie cały projekt) wszystko działa ok (musiałam jednak dodać opcję -l sqlite3 do kompilatora poprzez Narzędzia -> Opcje kompilatora -> Dodaj te polecenia do wiersza poleceń kompilatora, bez tego pojawiał się dokładnie ten sam błąd, co powyżej).

Podejrzewam, że to jakiś problem z opcjami kompilatora, ale zupełnie nie wiem jakimi i jak je poprawnie ustawić w Dev C++. Bardzo proszę o pomoc.
P-156190
mokrowski
» 2017-01-07 22:49:20
Gdybam bo logi nie pokazują wywołania kompilatora.
Stawiam na brak opcji -L  z podaniem katalogu z biblioteką sqlite3.
P-156191
Leyla
Temat założony przez niniejszego użytkownika
» 2017-01-07 22:56:28
Logi kompilacji:
Compiling project changes...
--------
- Project Filename: A:\Programowanie\C++\test\Projekt2.dev
- Compiler Name: TDM-GCC 4.9.2 32-bit Release

Building makefile...
--------
- Filename: A:\Programowanie\C++\test\Makefile.win
- Resource File: A:\Programowanie\C++\test\Projekt2_private.res

Processing makefile...
--------
- Makefile Processor: B:\Program Files\Dev-Cpp\MinGW64\bin\mingw32-make.exe
- Command: mingw32-make.exe -f "A:\Programowanie\C++\test\Makefile.win" all

g++.exe -c main.cpp -o main.o -I"B:/Program Files/Dev-Cpp/MinGW64/include" -I"B:/Program Files/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"B:/Program Files/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -I"B:/Program Files/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++" -m32 -l sqlite3

main.cpp: In function 'void database()':
main.cpp:25:9: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
     sql = "SELECT Title from book where Title like '%chiwum%'";
         ^

windres.exe -i Projekt2_private.rc -F pe-i386 --input-format=rc -o Projekt2_private.res -O coff

g++.exe main.o Projekt2_private.res -o Projekt2.exe -L"B:/Program Files/Dev-Cpp/MinGW64/lib32" -L"B:/Program Files/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib32" -static-libgcc -m32

main.o:main.cpp:(.text+0x87): undefined reference to `sqlite3_open'
main.o:main.cpp:(.text+0xba): undefined reference to `sqlite3_exec'
main.o:main.cpp:(.text+0xc5): undefined reference to `sqlite3_close'
collect2.exe: error: ld returned 1 exit status

A:\Programowanie\C++\test\Makefile.win:26: recipe for target 'Projekt2.exe' failed

mingw32-make.exe: *** [Projekt2.exe] Error 1


Compilation results...
--------
- Errors: 1
- Warnings: 1
- Compilation Time: 3,59s
Biblioteka sqlite3.h znajduje się w lokalizacji standardowych bibliotek (dołączona tam poprzez Narzędzia -> Package manager).

Zawartość pliku Makefile.win:
C/C++
# Project: Projekt2
# Makefile created by Dev-C++ 5.11

CPP = g++.exe
CC = gcc.exe
WINDRES = windres.exe
RES = Projekt2_private.res
OBJ = main.o $( RES )
LINKOBJ = main.o $( RES )
LIBS = - L"B:/Program Files/Dev-Cpp/MinGW64/lib32" - L"B:/Program Files/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib32" - static - libgcc - m32
INCS = - I "B:/Program Files/Dev-Cpp/MinGW64/include" - I "B:/Program Files/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" - I "B:/Program Files/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include"
CXXINCS = - I "B:/Program Files/Dev-Cpp/MinGW64/include" - I "B:/Program Files/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" - I "B:/Program Files/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" - I "B:/Program Files/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++"
BIN = Projekt2.exe
CXXFLAGS = $( CXXINCS ) - m32 - l sqlite3
CFLAGS = $( INCS ) - m32 - l sqlite3
RM = rm.exe - f

.PHONY
    : all all - before all - after clean clean - custom all
    : all - before $( BIN ) all - after clean
    : clean - custom $
{ RM } $( OBJ ) $( BIN )

$( BIN )
    : $( OBJ ) $( CPP ) $( LINKOBJ ) - o $( BIN ) $( LIBS ) main.o
    : main.cpp $( CPP ) - c main.cpp - o main.o $( CXXFLAGS ) Projekt2_private.res
    : Projekt2_private.rc $( WINDRES ) - i Projekt2_private.rc - F pe - i386--input - format = rc - o Projekt2_private.res - O coff
P-156192
mokrowski
» 2017-01-07 23:13:23
@Leyla, sqlite3.h to nie jest biblioteka. To nagłówek. Powiedz lepiej gdzie leży plik *.lib/*.dll z tą biblioteką i wskaż -L ten katalog (nie mam teraz pod ręką MS Win oraz takiego środowiska jakie Ty masz).
P-156193
Leyla
Temat założony przez niniejszego użytkownika
» 2017-01-08 02:23:26
Chyba faktycznie nie mógł sobie znaleźć tej .dll. Ostateczne rozwiązanie problemu wygląda następująco:
1. Należy "zainstalować" sqlite globalnie na komputerze i dodać ją do ścieżki systemowej (zrobiłam to według: https://www.tutorialspoint.com​/sqlite/sqlite_installation.htm):
   - ze strony http://www.sqlite.org​/download.html pobrałam sqlite-amalgamation-x.zip, sqlite-dll-win32-x86-x.zip, sqlite-tools-win32-x86-x.zip,
   - stworzyłam folder C:\sqlite (w zasadzie może być dowolny, w dowolnym miejscu) i skopiowałam do niego sqlite3.dll oraz sqlite3.def z paczki drugiej i sqlite3.exe z paczki trzeciej,
   - dodałam folder C:\sqlite do ścieżki systemowej PATH,
2. Z paczki sqlite-amalgamation-x.zip dodałam do projektu pliki sqlite3.h oraz sqlite3.c (prawy przycisk myszy na nazwę projektu w drzewie po lewej -> Dodaj do projektu).
3. Do programu dołączam plik nagłówkowy poprzez #include "sqlite3.h" (a nie, jak wcześniej, przez #include <sqlite3.h>).
4. I na koniec dodatkowe ustawienie kompilatora: Narzędzia -> Opcje kompilatora -> zakładka Kompilator -> Dodaj te polecenia do wiersza poleceń kompilatora -> i wkleiłam -l sqlite3.

@mokrowski bardzo dziękuję Ci za pomoc i zaangażowanie. :)
P-156196
« 1 »
  Strona 1 z 1