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łkowitych są gwarantowane 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
istdint.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łniC++17
standard językowy każesz mu skompilować zCMAKE_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 naconfig.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.