sql >> Databasteknik >  >> RDS >> Mysql

MySQL- och MariaDB-bibliotek i C++ med cmake, mingw

Båda anslutningarna MySQL såväl som MariaDB (som delar samma arv ) är avsedda att endast kompileras och användas med Visual Studio på Windows . Du hittar många tidigare frågor om StackOverflow angående det. Problemet med dem är att de definierar många strukturer som redan är definierade i standardbiblioteket och sedan länkar till standardbiblioteket också.

Jag föreslår att du byter till Visual Studio eller till ett Linux-system . Om du måste använda GCC under Windows, leta efter en annan kontakt. Dessa problem kommer inte att lösas lätt. Om så är fallet är det osannolikt att lösningarna är portabla och kanske inte fungerar med framtida versioner av de två kontakterna. Du kan ta en titt på alternativen SQLite och SQLAPI++ .

Första problemet:heltal med fast bredd

Det första problemet du nämner är faktiskt relaterat till heltalstyper med fast bredd och 32-bitars operativsystem definierade i header-filerna. Det finns traditionella heltalstyper som char , short , int , long och long long men dessutom de tidigare nämnda heltal med fast bredd.

MySql Connector definierar int32_t datatyp i config.h och även standard C++-biblioteket definierar dem:MySql definierar int32_t med kompilatorns datatyp __int32

typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;

som överraskande nog visar sig vara den long int datatyper

typedef long int int32_t;
typedef long unsigned int uint32_t;

medan standardbiblioteket definierar dem som vanliga int

typedef int int32_t;
typedef unsigned int uint32_t;

long heltalsdatatyper är garanterat att vara minst 32-bitars :På en 32-bitars arkitektur en long int är 32-bitars (precis som en int ) medan de för 64-bitars har olika längder - en long int är 64-bitars och en int är bara 32-bitars (se här ). Detta betyder faktiskt att för ett 32-bitarssystem bör dessa definitioner vara identiska men ändå anser kompilatorn att de är motstridiga.

MySql-huvudet är omslutet av olika definitioner (jag lägger en förklaring bredvid dem så att du kan förstå varför de föreslagna lösningarna nedan faktiskt fungerar) som avgör om motsvarande datatyper ska definieras eller inte

// 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

Lösningar

Baserat på strukturen för rubrikfilen ovan finns det ett par lösningar för detta. Vissa kan vara mer lönsamma medan andra mindre.

  • Uppenbarligen kunde du inte inkludera några typdefinitioner i cstdint och stdint.h och leva med MySql definierar. Detta skulle faktiskt vara ganska begränsande eftersom en annan standardbibliotekshuvud förr eller senare kommer att inkludera det och det kan leda till att du tvingas inte använda standardbiblioteket alls, vilket kan vara mycket begränsande.

  • Du kan helt och hållet överge den 32-bitars byggverktygskedja du använder, byta till en **64-bitars kompilator och kompilera för 64-bitars . I det här fallet bör detta inte hända som rubriken config.h i MySql ingår endast för 32-bitars system enligt ovan! Om det inte finns någon bra anledning till att ditt projekt ska vara 32-bitars är det vad jag faktiskt skulle göra. På tal om din kompilator:Du verkar använda GCC 6.3.0 som släpptes redan 2016 och faktiskt stödjer inte helt C++17 språkstandard du säger åt den att kompilera med CMAKE_CXX_STANDARD 17 i din CMake-fil. Du kanske vill använda en annan nyare kompilator om du vill använda C++17-funktioner i stor utsträckning. Annars är C++14 inte så dåligt heller.

  • Du kan använda Visual Studio 2010 (version 1600 ) eller senare för kompilering som i detta fall kommer rubriken automatiskt att inkludera definitionerna från standarden istället för att definiera sina egna.

  • Du kan definiera förprocessorflaggan #define CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES ovanpå din kod (eller inuti den IDE du använder för ditt projekt) som om den här flaggan är inställd på config.h filen kommer inte att definiera några datatyper.

  • På samma sätt kan du också lösa det genom att öppna MYSQLC~1.0/include/jdbc/cppconn/config.h och ändra förbearbetningsdirektiven från

    #define HAVE_MS_INT32  1
    #define HAVE_MS_UINT32 1
    

    till

    #define HAVE_MS_INT32  0
    #define HAVE_MS_UINT32 0
    

    Detta kommer att avaktivera motsvarande definitioner för alla program som du också skriver i framtiden som inkluderar denna rubrik.

Andra problemet:Länka till bibliotek kompilerade med Visual Studio

Det andra felmeddelandet du får är faktiskt relaterat till att länka biblioteket. På Windows är bibliotek som kompileras med olika kompilatorer i allmänhet inte kompatibla. Detta innebär att ett program som kompilerats med GCC inte kan inkludera bibliotek som kompilerats med Visual Studio. I ditt fall kompilerades DLL-filen med Visual Studio och därför misslyckas länkningen till ditt GCC-program.

Som också nämnts här du kan tvinga CMake att använda MinGW istället för Visual Studio med cmake -G "MinGW Makefiles" men jag har provat det och det fungerar varken med MariaDB eller MySQL.

Använda MSYS2 i MySQL får jag ett kryptiskt fel relaterat till OpenSSL när jag är på MariaDB efter officiell guide och sedan använda

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

Jag måste göra ett par manuella ändringar, som att modifiera /src/CArrayImp.h och ändra rad 59 till 63 från

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

till

#define ZEROI64 0LL

som 0I64 definieras endast av Visual Studio. Dessutom måste man ta bort mallinstansieringen i CArray.cpp men jag får fortfarande en The system cannot find the path specified. felmeddelande. På samma sätt kunde jag inte få det att kompilera i Cygwin.

Alternativ för SQL C++-anslutningar

Jag har ingen lösning på det sista problemet men du kanske vill ta en titt på alternativ. Du kan ladda ner SQLite från källan och kompilera den. Enligt installationsguide från källan den är kompatibel med MinGW men den är bara lättvikts a> . Så borde vara Shareware SQLAPI++ . Enligt deras "Beställ"-sida testversionen för Windows är fullt fungerande

Båda bör stödja MySql:t.ex. se här .

tl;dr: Använd MySQL- och MariaDB-anslutningarna endast Windows i Visual Studio . Om du inte kan använda Visual Studio, ta en titt på de alternativa C++ SQL-anslutningarna som SQLite och SQLAPI++ istället.



  1. Använda icke-fångande grupper i MySQL REGEXP

  2. Hur man bestämmer tabellstorlek i Oracle

  3. Npgsql med Pgbouncer på Kubernetes - pooling &keepalives

  4. SQL server 2005 numerisk precision förlust