Oba konektory MySQL i MariaDB (které sdílejí stejné dědictví ) jsou určeny ke kompilaci a použití pouze se sadou Visual Studio v systému Windows . Na StackOverflow ohledně toho najdete spoustu předchozích otázek. Problém s nimi je v tom, že definují spoustu struktur, které jsou již definovány ve standardní knihovně a pak se také na standardní knihovnu odkazují.
Navrhuji, abyste přešli na Visual Studio nebo na systém Linux . Pokud musíte použít GCC pod Windows, vyhledejte jiný konektor. Tyto problémy se nevyřeší snadno. Pokud ano, řešení pravděpodobně nebudou přenosná a nemusí fungovat s budoucími verzemi těchto dvou konektorů. Můžete se podívat na alternativy SQLite a SQLAPI++ .
První problém:celá čísla s pevnou šířkou
První problém, který zmiňujete, ve skutečnosti souvisí s typy celých čísel s pevnou šířkou
a 32bitové operační systémy definované v hlavičkových souborech. Existují tradiční celočíselné typy jako char
, short
, int
, long
a long long
ale navíc výše zmíněná celá čísla s pevnou šířkou.
Konektor MySql definuje int32_t
datový typ v config.h
a také je definuje standardní knihovna C++:MySql definuje int32_t
s datovým typem kompilátoru __int32
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
což se překvapivě ukáže jako long int
datové typy
typedef long int int32_t;
typedef long unsigned int uint32_t;
zatímco standardní knihovna je definuje jako běžné int
typedef int int32_t;
typedef unsigned int uint32_t;
long
celočíselné datové typy jsou zaručeně alespoň 32bitové :Na 32bitové architektuře long int
je 32bitový (stejně jako int
), zatímco pro 64bitové mají různé délky - long int
je 64bitový a má int
je pouze 32bitový (viz zde
). To ve skutečnosti znamená, že pro 32bitový systém by tyto definice měly být totožné, ale přesto si kompilátor myslí, že jsou v rozporu.
Záhlaví MySql je obaleno různými definicemi (vedle nich jsem dal vysvětlení, abyste pochopili, proč navrhovaná řešení uvedená níže skutečně fungují), které rozhodují, zda by měly být definovány odpovídající datové typy nebo ne
// 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
Řešení
Na základě výše uvedené struktury hlavičkového souboru existuje několik řešení. Některé mohou být životaschopnější, zatímco jiné méně.
-
Je zřejmé, že do
cstdint
nemůžete zahrnout žádné definice typů astdint.h
a žít s definicemi MySql. To by ve skutečnosti bylo docela omezující, protože dříve nebo později to pravděpodobně bude obsahovat jiná hlavička standardní knihovny a mohlo by to vést k tomu, že budete nuceni standardní knihovnu vůbec nepoužívat, což může být velmi omezující. -
Mohli byste úplně opustit 32bitový řetězec nástrojů sestavování, který používáte, přejít na **64bitový kompilátor a kompilovat pro 64bitové . V tomto případě by se to nemělo stát jako hlavička
config.h
v MySql je zahrnuto pouze pro 32bitové systémy, jak je uvedeno výše! Pokud neexistuje žádný dobrý důvod, že by váš projekt měl být 32bitový, udělal bych to. Když mluvíme o vašem kompilátoru:Zdá se, že používáte GCC 6.3.0, který byl vydán v roce 2016 a ve skutečnosti nepodporuje plněC++17
jazykový standard říkáte mu, aby se zkompiloval sCMAKE_CXX_STANDARD 17
ve vašem souboru CMake. Možná budete chtít použít jiný novější kompilátor v případě, že chcete široce využívat funkce C++17. Jinak C++14 také není špatné. -
Můžete použít Visual Studio 2010 (verze
1600
) nebo později pro kompilaci jako v tomto případě bude hlavička automaticky obsahovat definice ze standardu namísto definování vlastních. -
Můžete definovat příznak předprocesoru
#define CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES
nad vaším kódem (nebo uvnitř IDE, které používáte pro svůj projekt), jako by tento příznak byl nastaven naconfig.h
soubor nebude definovat žádné datové typy. -
Podobně byste to mohli vyřešit otevřením
MYSQLC~1.0/include/jdbc/cppconn/config.h
a upravit direktivy pre-procesoru od#define HAVE_MS_INT32 1 #define HAVE_MS_UINT32 1
do
#define HAVE_MS_INT32 0 #define HAVE_MS_UINT32 0
Tím deaktivujete odpovídající definice pro všechny programy, které také v budoucnu píšete a které obsahují tuto hlavičku.
Druhý problém:Propojení s knihovnami zkompilovanými pomocí sady Visual Studio
Druhá chybová zpráva, kterou dostanete, ve skutečnosti souvisí s propojením knihovny. Knihovny ve Windows kompilované různými kompilátory obecně nejsou kompatibilní. To znamená, že program kompilovaný pomocí GCC nemůže obsahovat knihovny kompilované pomocí Visual Studia. Ve vašem případě byla knihovna DLL zkompilována pomocí sady Visual Studio, a proto selhalo propojení s vaším programem GCC.
Jak je také uvedeno zde
můžete přinutit CMake, aby místo Visual Studia používal MinGW pomocí cmake -G "MinGW Makefiles"
ale zkusil jsem to a nefunguje to ani s MariaDB ani s MySQL.
Pomocí MSYS2 v MySQL dostávám kryptickou chybu související s OpenSSL, zatímco na MariaDB následuje oficiální průvodce a poté 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
Musím provést několik ručních úprav, jako je úprava /src/CArrayImp.h
a změňte řádek 59 na 63 z
#ifndef _WIN32
# define ZEROI64 0LL
#else
# define ZEROI64 0I64
#endif
do
#define ZEROI64 0LL
jako 0I64
je definováno pouze aplikací Visual Studio. Dále je třeba odstranit konkretizaci šablony v CArray.cpp
ale stejně skončím s The system cannot find the path specified.
chybové hlášení. Podobně jsem nebyl schopen jej zkompilovat v Cygwin.
Alternativy konektoru SQL C++
Nemám žádné řešení pro poslední problém, ale možná se budete chtít podívat na alternativy. Můžete si stáhnout SQLite ze zdroje a zkompilujte jej. Podle příručky k instalaci ze zdroje je kompatibilní s MinGW, ale je pouze lehký . Stejně tak by měl být Shareware SQLAPI++ . Podle jejich stránky "Objednávka" zkušební verze pro Windows je plně funkční
Oba by měli podporovat MySql:např. viz zde .
tl;dr: Používejte konektory MySQL a MariaDB v Windows pouze v sadě Visual Studio . Pokud nemůžete používat Visual Studio, podívejte se na alternativní C++ SQL konektory, jako je SQLite a SQLAPI++ místo toho.