sql >> Databáze >  >> RDS >> Mysql

Knihovny MySQL a MariaDB v C++ pomocí cmake, mingw

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ů a stdint.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 s CMAKE_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 na config.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.



  1. PDO odstraní zadaný řádek z tabulky

  2. Ovladač HikariCP Postgresql tvrdí, že nepřijímá JDBC URL

  3. Jak zkontrolovat data časového rozsahu leží mezi dvěma daty v dotazu mysql

  4. Mysql adaptér pro Zend_Translate