Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Biblioteki MySQL i MariaDB w C++ przy użyciu cmake, mingw

Oba konektory MySQL i MariaDB (które mają to samo dziedzictwo ) są przeznaczone do kompilacji i używania tylko z programem Visual Studio w systemie Windows . Na StackOverflow znajdziesz wiele wcześniejszych pytań na ten temat. Problem z nimi polega na tym, że definiują wiele struktur, które są już zdefiniowane w bibliotece standardowej, a następnie łączą się również z biblioteką standardową.

Proponuję przełączyć się na Visual Studio lub na system Linux . Jeśli musisz używać GCC pod Windows, poszukaj innego złącza. Te problemy nie będą łatwe do rozwiązania. Jeśli tak, rozwiązania prawdopodobnie nie będą przenośne i mogą nie działać z przyszłymi wersjami dwóch złączy. Możesz rzucić okiem na alternatywy SQLite i SQLAPI++ .

Pierwszy problem:liczby całkowite o stałej szerokości

Pierwszy problem, o którym wspominasz, jest w rzeczywistości związany z typami liczb całkowitych o stałej szerokości i 32-bitowe systemy operacyjne zdefiniowane w plikach nagłówkowych. Istnieją tradycyjne typy liczb całkowitych, takie jak char , short , int , long i long long ale dodatkowo wspomniane wcześniej liczby całkowite o stałej szerokości.

Łącznik MySql definiuje int32_t typ danych w config.h a także definiuje je standardowa biblioteka C++:MySql definiuje int32_t z typem danych kompilatora __int32

typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;

co zaskakująco okazuje się być long int typy danych

typedef long int int32_t;
typedef long unsigned int uint32_t;

podczas gdy standardowa biblioteka definiuje je jako zwykły int

typedef int int32_t;
typedef unsigned int uint32_t;

long typy danych całkowitychgwarantowane co najmniej 32-bitowe :Na 32-bitowej architekturze long int jest 32-bitowy (tak jak int ), podczas gdy dla 64-bitów mają różne długości - long int jest 64-bitowy i int jest tylko 32-bitowy (patrz tutaj ). Oznacza to, że w rzeczywistości dla systemu 32-bitowego te definicje powinny być identyczne, ale kompilator uważa, że ​​są ze sobą sprzeczne.

Nagłówek MySql jest otoczony różnymi definicjami (obok nich umieściłem wyjaśnienie, aby można było zrozumieć, dlaczego proponowane poniżej rozwiązania faktycznie działają), które decydują, czy należy zdefiniować odpowiednie typy danych, czy nie

// Only define for 32-bit compilation
#if defined(_WIN32)
// Don't define if this custom flag is activated
#ifndef CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES
// Do not define for Visual Studio 2010 and later (but use C++ standard library instead)
#if _MSC_VER >= 1600
#include <stdint.h>
#else
// Only define if HAVE_MS_INT32 (another custom flag) is set to true (1)
#ifdef HAVE_MS_INT32
typedef __int32 int32_t;
#endif
// Some more data type defines...
#endif
#endif
#endif

Rozwiązania

W oparciu o strukturę pliku nagłówkowego podaną powyżej istnieje kilka rozwiązań tego problemu. Niektóre mogą być bardziej opłacalne, a inne mniej.

  • Oczywiście nie możesz włączyć żadnych definicji typów w cstdint i stdint.h i żyć z definicjami MySQL. Byłoby to w rzeczywistości dość ograniczające, ponieważ prędzej czy później prawdopodobnie inny nagłówek biblioteki standardowej będzie go zawierał i może zmusić cię do nieużywania biblioteki standardowej, co może być bardzo ograniczające.

  • Możesz całkowicie zrezygnować z 32-bitowego łańcucha narzędzi do kompilacji, którego używasz, przełączyć się na **kompilator 64-bitowy i kompilować dla 64-bitów . W takim przypadku nie powinno się to zdarzyć, ponieważ nagłówek config.h w MySql jest dostępny tylko dla systemów 32-bitowych, jak wspomniano powyżej! Jeśli nie ma dobrego powodu, dla którego twój projekt powinien być 32-bitowy, tak właśnie bym zrobił. Mówiąc o swoim kompilatorze:Wydaje się, że używasz GCC 6.3.0, który został wydany w 2016 roku, a właściwie nie obsługuje w pełni C++17 standard językowy każesz mu skompilować z CMAKE_CXX_STANDARD 17 w pliku CMake. Możesz użyć innego, nowszego kompilatora, jeśli chcesz intensywnie korzystać z funkcji C++17. W przeciwnym razie C++14 też nie jest taki zły.

  • Możesz użyć Visual Studio 2010 (wersja 1600 ) lub później do kompilacji, tak jak w tym przypadku, nagłówek automatycznie będzie zawierał definicje ze standardu zamiast definiować własne.

  • Możesz zdefiniować flagę preprocesora #define CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES nad kodem (lub wewnątrz IDE, którego używasz w swoim projekcie), tak jakby ta flaga była ustawiona na config.h plik nie definiuje żadnych typów danych.

  • Podobnie możesz rozwiązać ten problem, otwierając MYSQLC~1.0/include/jdbc/cppconn/config.h i zmodyfikować dyrektywy preprocesora od

    #define HAVE_MS_INT32  1
    #define HAVE_MS_UINT32 1
    

    do

    #define HAVE_MS_INT32  0
    #define HAVE_MS_UINT32 0
    

    Spowoduje to dezaktywację odpowiednich definicji dla wszystkich programów, które również napiszesz w przyszłości, które zawierają ten nagłówek.

Drugi problem:łączenie z bibliotekami skompilowanymi za pomocą Visual Studio

Drugi komunikat o błędzie, który otrzymujesz, jest w rzeczywistości związany z łączeniem biblioteki. W systemie Windows biblioteki skompilowane przy użyciu różnych kompilatorów generalnie nie są kompatybilne. Oznacza to, że program skompilowany za pomocą GCC nie może zawierać bibliotek skompilowanych za pomocą Visual Studio. W twoim przypadku biblioteka DLL została skompilowana za pomocą programu Visual Studio i dlatego połączenie z programem GCC kończy się niepowodzeniem.

Jak również wspomniano tutaj możesz zmusić CMake do używania MinGW zamiast Visual Studio za pomocą cmake -G "MinGW Makefiles" ale próbowałem go i nie działa z MariaDB ani MySQL.

Korzystanie z MSYS2 w MySQL otrzymuję tajemniczy błąd związany z OpenSSL podczas korzystania z MariaDB zgodnie z oficjalny przewodnik a następnie za pomocą

cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -G "MinGW Makefiles" -DCONC_WITH_UNIT_TESTS=Off -DCONC_WITH_MSI=OFF -DWITH_SSL=SCHANNEL .
cmake --build . --config RelWithDebInfo

Muszę wykonać kilka ręcznych modyfikacji, takich jak modyfikacja /src/CArrayImp.h i zmień linię 59 na 63 z

#ifndef _WIN32
# define ZEROI64 0LL
#else
# define ZEROI64 0I64
#endif

do

#define ZEROI64 0LL

jako 0I64 jest definiowana tylko przez program Visual Studio. Ponadto należy usunąć instancję szablonu w CArray.cpp ale nadal kończę z The system cannot find the path specified. Komunikat o błędzie. Podobnie nie udało mi się go skompilować w Cygwinie.

Alternatywne konektory SQL C++

Nie mam rozwiązania na ostatni problem, ale warto przyjrzeć się alternatywom. Możesz pobrać SQLite ze źródła i skompiluj go. Zgodnie z przewodnikiem instalacji ze źródła jest kompatybilny z MinGW, ale jest tylko lekki . Podobnie powinno być Shareware SQLAPI++ . Według ich strona „Zamów” wersja próbna dla systemu Windows jest w pełni funkcjonalna

Oba powinny obsługiwać MySql:m.in. zobacz tutaj .

tl;dr: Używaj łączników MySQL i MariaDB w Windowsie tylko w Visual Studio . Jeśli nie możesz korzystać z Visual Studio, spójrz na alternatywne konektory C++ SQL, takie jak SQLite i SQLAPI++ zamiast tego.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Relacja „wiele do dwóch”

  2. Kiedy wybrać Oracle zamiast MySQL?

  3. mysql_real_escape_string VS dodaje ukośniki

  4. Łączenie wierszy wyników node-mysql w pojedynczy zwrot JSON dla node.js

  5. Jak napisać utworzyć użytkownika ? z przygotowanym zestawieniem MySQL