sql >> Database >  >> RDS >> Mysql

MySQL- en MariaDB-bibliotheek in C++ met cmake, mingw

Beide connectoren MySQL en MariaDB (die dezelfde erfenis delen ) zijn alleen bedoeld om te worden gecompileerd en gebruikt met Visual Studio op Windows . U vindt er veel eerdere vragen over StackOverflow over. Het probleem met hen is dat ze veel structuren definiëren die al in de standaardbibliotheek zijn gedefinieerd en vervolgens ook naar de standaardbibliotheek linken.

Ik raad je aan om over te schakelen naar Visual Studio of naar een Linux-systeem . Als u GCC onder Windows moet gebruiken, zoek dan naar een andere connector. Deze problemen zijn niet zomaar op te lossen. Als dit het geval is, zijn de oplossingen waarschijnlijk niet draagbaar en werken ze mogelijk niet met toekomstige versies van de twee connectoren. U kunt de alternatieven SQLite bekijken en SQLAPI++ .

Eerste probleem:gehele getallen met vaste breedte

Het eerste probleem dat u noemt, heeft te maken met de integer typen met vaste breedte en 32-bits besturingssystemen gedefinieerd in de header-bestanden. Er zijn de traditionele typen integers zoals char , short , int , long en long long maar daarnaast de bovengenoemde gehele getallen met vaste breedte.

De MySql-connector definieert de int32_t gegevenstype in config.h en ook de standaard C++-bibliotheek definieert ze:MySql definieert de int32_t met het compilergegevenstype __int32

typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;

wat verrassend genoeg de long int . blijkt te zijn gegevenstypen

typedef long int int32_t;
typedef long unsigned int uint32_t;

terwijl de standaardbibliotheek ze definieert als gewone int

typedef int int32_t;
typedef unsigned int uint32_t;

long gegevenstypen integer zijn gegarandeerd minimaal 32-bits :Op een 32-bits architectuur een long int is 32-bits (net als een int ) terwijl ze voor 64-bit verschillende lengtes hebben - een long int is 64-bit en een int is slechts 32-bits (zie hier ). Dit betekent eigenlijk voor een 32-bits systeem dat deze definities identiek zouden moeten zijn, maar toch denkt de compiler dat ze tegenstrijdig zijn.

De MySql-header is omgeven door verschillende definities (ik heb er een uitleg naast gezet zodat u kunt begrijpen waarom de voorgestelde oplossingen hieronder echt werken) die bepalen of de bijbehorende gegevenstypen moeten worden gedefinieerd of niet

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

Oplossingen

Op basis van de structuur van het bovenstaande headerbestand zijn hier een aantal oplossingen voor. Sommige zijn misschien meer levensvatbaar, andere minder.

  • Het is duidelijk dat u geen typedefinities in cstdint kunt opnemen en stdint.h en leef met de MySql-definities. Dit zou eigenlijk behoorlijk beperkend zijn, aangezien het vroeg of laat waarschijnlijk is dat een andere standaardbibliotheekkop het zal bevatten en het kan ertoe leiden dat u gedwongen wordt om de standaardbibliotheek helemaal niet te gebruiken, wat zeer beperkend kan zijn.

  • U kunt de 32-bits build-toolketen die u gebruikt helemaal verlaten, overschakelen naar een **64-bits compiler en compileren voor 64-bits . In dit geval zou dit niet moeten gebeuren als de header config.h in MySql is alleen inbegrepen voor 32-bits systemen zoals hierboven vermeld! Als er geen goede reden is dat uw project 32-bits zou moeten zijn, zou ik dat eigenlijk doen. Over je compiler gesproken:je lijkt GCC 6.3.0 te gebruiken die in 2016 werd uitgebracht en eigenlijk ondersteunt niet volledig de C++17 taalstandaard je vertelt het te compileren met CMAKE_CXX_STANDARD 17 in je CMake-bestand. Misschien wilt u een andere nieuwere compiler gebruiken voor het geval u de C++17-functies uitgebreid wilt gebruiken. Anders is C++14 ook niet slecht.

  • U kunt Visual Studio 2010 . gebruiken (versie 1600 ) of later voor compilatie, aangezien in dit geval de kop automatisch de definities van de standaard zal bevatten in plaats van zijn eigen definities te definiëren.

  • U kunt de pre-processorvlag definiëren #define CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES bovenop uw code (of binnen de IDE die u voor uw project gebruikt) alsof deze vlag is ingesteld op de config.h bestand definieert geen gegevenstypes.

  • Op dezelfde manier zou je het ook kunnen oplossen door MYSQLC~1.0/include/jdbc/cppconn/config.h te openen en wijzig de pre-processor richtlijnen van

    #define HAVE_MS_INT32  1
    #define HAVE_MS_UINT32 1
    

    naar

    #define HAVE_MS_INT32  0
    #define HAVE_MS_UINT32 0
    

    Dit zal de overeenkomstige definities deactiveren voor alle programma's die u in de toekomst ook schrijft en die deze koptekst bevatten.

Tweede probleem:linken naar bibliotheken die zijn gecompileerd met Visual Studio

De tweede foutmelding die u krijgt, is eigenlijk gerelateerd aan het koppelen van de bibliotheek. Op Windows zijn bibliotheken die met verschillende compilers zijn gecompileerd over het algemeen niet compatibel. Dit betekent dat een programma dat is gecompileerd met GCC geen bibliotheken kan bevatten die zijn gecompileerd met Visual Studio. In jouw geval is de DLL gecompileerd met Visual Studio en daarom mislukt de koppeling naar je GCC-programma.

Zoals ook vermeld hier je kunt CMake dwingen om MinGW te gebruiken in plaats van Visual Studio met cmake -G "MinGW Makefiles" maar ik heb het geprobeerd en het werkt niet met MariaDB of MySQL.

MSYS2 gebruiken in MySQL krijg ik een cryptische fout gerelateerd aan OpenSSL terwijl ik op MariaDB de officiële gids en dan met behulp van

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

Ik moet een aantal handmatige aanpassingen doen, zoals het aanpassen van /src/CArrayImp.h en verander regel 59 naar 63 van

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

naar

#define ZEROI64 0LL

als 0I64 wordt alleen gedefinieerd door Visual Studio. Verder moet men de sjablooninstantiatie in CArray.cpp . verwijderen maar ik krijg nog steeds een The system cannot find the path specified. foutmelding. Op dezelfde manier kon ik het niet compileren in Cygwin.

Alternatieven voor SQL C++-connector

Ik heb geen oplossing voor het laatste probleem, maar misschien wil je alternatieven bekijken. Je zou SQLite kunnen downloaden van de bron en compileer het. Volgens de installatiegids van de bron het is compatibel met MinGW, maar het is alleen lichtgewicht . Zo zou de Shareware SQLAPI++ moeten zijn . Volgens hun "Order"-pagina de proefversie voor Windows is volledig functioneel

Beide moeten MySql ondersteunen:b.v. zie hier .

tl;dr: Gebruik de MySQL- en MariaDB-connectoren op Windows alleen in Visual Studio . Als je Visual Studio niet kunt gebruiken, kijk dan eens naar de alternatieve C++ SQL-connectors zoals SQLite en SQLAPI++ in plaats daarvan.



  1. Levensverzekeringsgegevensmodel

  2. Zoek uit of een string alleen ASCII-tekens bevat

  3. Hoe van tekst naar int te casten als de kolom zowel int- als NULL-waarden bevat in PostgreSQL

  4. Hoe waarden te vermenigvuldigen met SQL