sql >> Database teknologi >  >> RDS >> Mysql

MySQL- og MariaDB-biblioteker i C++ ved hjælp af cmake, mingw

Begge connectorer MySQL såvel som MariaDB (som deler den samme arv ) er kun beregnet til at blive kompileret og brugt med Visual Studio på Windows . Du vil finde en masse tidligere spørgsmål om StackOverflow angående det. Problemet med dem er, at de definerer en masse strukturer, der allerede er defineret i standardbiblioteket og derefter også linker til standardbiblioteket.

Jeg foreslår, at du enten skifter til Visual Studio eller til et Linux-system . Hvis du skal bruge GCC under Windows, skal du kigge efter et andet stik. Disse problemer vil ikke blive løst let. Hvis det er tilfældet, er det usandsynligt, at løsningerne er bærbare og fungerer muligvis ikke med fremtidige versioner af de to stik. Du kan se på alternativerne SQLite og SQLAPI++ .

Første problem:heltal med fast bredde

Det første problem, du nævner, er faktisk relateret til heltalstyper med fast bredde og 32-bit operativsystemer defineret i header-filerne. Der er de traditionelle heltalstyper som char , short , int , long og long long men derudover de førnævnte heltal med fast bredde.

MySql Connector definerer int32_t datatype i config.h og også standard C++ biblioteket definerer dem:MySql definerer int32_t med compilerdatatypen __int32

typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;

som overraskende viser sig at være den long int datatyper

typedef long int int32_t;
typedef long unsigned int uint32_t;

mens standardbiblioteket definerer dem som almindelige int

typedef int int32_t;
typedef unsigned int uint32_t;

long heltalsdatatyper er garanteret at være mindst 32-bit :På en 32-bit arkitektur en long int er 32-bit (ligesom en int ) mens de for 64-bit har forskellige længder - en long int er 64-bit og en int er kun 32-bit (se her ). Dette betyder faktisk for et 32-bit system, at disse definitioner burde være identiske, men alligevel mener compileren, at de er modstridende.

MySql-headeren er pakket ind af forskellige definitioner (jeg sætter en forklaring ved siden af ​​dem, så du kan forstå, hvorfor de foreslåede løsninger, der er angivet nedenfor, rent faktisk virker), som afgør, om de tilsvarende datatyper skal defineres eller ej

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

Baseret på strukturen af ​​header-filen ovenfor er der et par løsninger til dette. Nogle er måske mere levedygtige, mens andre er mindre.

  • Det er klart, at du ikke kunne inkludere nogen typedefinitioner i cstdint og stdint.h og leve med MySql definerer. Dette ville faktisk være ret begrænsende, da en anden standardbiblioteksheader før eller siden sandsynligvis vil inkludere det, og det kan resultere i, at du tvinger dig til slet ikke at bruge standardbiblioteket, hvilket kan være meget begrænsende.

  • Du kan helt opgive den 32-bit byggeværktøjskæde, du bruger, skifte til en **64-bit compiler og kompilere til 64-bit . I dette tilfælde bør dette ikke ske som overskriften config.h i MySql er kun inkluderet for 32-bit systemer som nævnt ovenfor! Hvis der ikke er nogen god grund til, at dit projekt skal være 32-bit, er det, hvad jeg faktisk ville gøre. Taler om din compiler:Du ser ud til at bruge GCC 6.3.0, som blev udgivet tilbage i 2016 og faktisk understøtter ikke fuldt ud C++17 sprogstandard du beder den kompilere med CMAKE_CXX_STANDARD 17 i din CMake-fil. Du vil måske bruge en anden nyere compiler, hvis du vil bruge C++17-funktioner i udstrakt grad. Ellers er C++14 heller ikke så dårligt.

  • Du kan bruge Visual Studio 2010 (version 1600 ) eller senere til kompilering som i dette tilfælde vil overskriften automatisk inkludere definitionerne fra standarden i stedet for at definere sine egne.

  • Du kunne definere pre-processor flaget #define CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES oven på din kode (eller inde i den IDE, du bruger til dit projekt), som om dette flag er sat config.h fil vil ikke definere nogen datatyper.

  • På samme måde kan du også løse det ved at åbne MYSQLC~1.0/include/jdbc/cppconn/config.h og ændre pre-processor-direktiverne fra

    #define HAVE_MS_INT32  1
    #define HAVE_MS_UINT32 1
    

    til

    #define HAVE_MS_INT32  0
    #define HAVE_MS_UINT32 0
    

    Dette vil deaktivere de tilsvarende definerer for alle programmer, du også skriver i fremtiden, som inkluderer denne overskrift.

Andet problem:Link til biblioteker kompileret med Visual Studio

Den anden fejlmeddelelse, du får, er faktisk relateret til at linke biblioteket. På Windows er biblioteker, der er kompileret med forskellige compilere, generelt ikke kompatible. Dette betyder, at et program, der er kompileret med GCC, ikke kan inkludere biblioteker, der er kompileret med Visual Studio. I dit tilfælde blev DLL'en kompileret med Visual Studio, og derfor mislykkes linkningen til dit GCC-program.

Som også nævnt her du kan tvinge CMake til at bruge MinGW i stedet for Visual Studio med cmake -G "MinGW Makefiles" men jeg har prøvet det, og det virker hverken med MariaDB eller MySQL.

Brug af MSYS2 i MySQL får jeg en kryptisk fejl relateret til OpenSSL, mens jeg er på MariaDB efter officiel vejledning og derefter bruge

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

Jeg er nødt til at foretage et par manuelle ændringer, såsom at ændre /src/CArrayImp.h og skift linje 59 til 63 fra

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

til

#define ZEROI64 0LL

som 0I64 er kun defineret af Visual Studio. Ydermere skal man fjerne skabelonforekomsten i CArray.cpp men jeg ender stadig med en The system cannot find the path specified. fejl besked. På samme måde var jeg ikke i stand til at få det til at kompilere i Cygwin.

Alternativer til SQL C++-stik

Jeg har ingen løsning på det sidste problem, men du vil måske se på alternativer. Du kan downloade SQLite fra kilden og kompiler den. Ifølge installationsvejledningen fra kilden den er kompatibel med MinGW, men den er kun letvægt . Det burde også være Shareware SQLAPI++ . Ifølge deres "Bestil"-side prøveversionen til Windows er fuldt funktionel

Begge skal understøtte MySql:f.eks. se her .

tl;dr: Brug MySQL- og MariaDB-stikkene på kun Windows i Visual Studio . Hvis du ikke kan bruge Visual Studio, så kig på de alternative C++ SQL-forbindelser såsom SQLite og SQLAPI++ i stedet.



  1. PHP password_verify virker ikke mod databasen

  2. ændring af DEFAULT-begrænsning på kolonne SQL

  3. Opdater forespørgsel i Yii

  4. Sådan får du optegnelser fra sidste 24 timer i MySQL