Mysql
 sql >> Base de données >  >> RDS >> Mysql

Bibliothèque MySQL et MariaDB en C++ utilisant cmake, mingw

Les deux connecteurs MySQL ainsi que MariaDB (qui partagent le même héritage ) sont destinés à être compilés et utilisés avec Visual Studio sous Windows uniquement . Vous trouverez beaucoup de questions précédentes sur StackOverflow à ce sujet. Le problème avec eux est qu'ils définissent un grand nombre de structures qui sont déjà définies dans la bibliothèque standard, puis sont également liées à la bibliothèque standard.

Je vous suggère de passer à Visual Studio ou à un système Linux . Si vous devez utiliser GCC sous Windows, recherchez un autre connecteur. Ces problèmes ne seront pas résolus facilement. Si tel est le cas, les solutions ne seront probablement pas portables et pourraient ne pas fonctionner avec les futures versions des deux connecteurs. Vous pouvez consulter les alternatives SQLite et SQLAPI++ .

Premier problème :les entiers à largeur fixe

Le premier problème que vous mentionnez est en fait lié aux types entiers à largeur fixe et les systèmes d'exploitation 32 bits définis dans les fichiers d'en-tête. Il existe les types entiers traditionnels comme char , short , int , long et long long mais en plus les entiers à largeur fixe susmentionnés.

Le connecteur MySql définit le int32_t type de données dans config.h et aussi la bibliothèque standard C++ les définit :MySql définit le int32_t avec le type de données du compilateur __int32

typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;

qui s'avère étonnamment être le long int type de données

typedef long int int32_t;
typedef long unsigned int uint32_t;

tandis que la bibliothèque standard les définit comme des int normaux

typedef int int32_t;
typedef unsigned int uint32_t;

long types de données entiers sont garantis au moins 32 bits :Sur une architecture 32 bits un long int est 32 bits (tout comme un int ) tandis que pour 64 bits, ils ont des longueurs différentes - un long int est 64 bits et un int est uniquement 32 bits (voir ici ). Cela signifie en fait que pour un système 32 bits, ces définitions devraient être identiques mais que le compilateur pense qu'elles sont en conflit.

L'en-tête MySql est enveloppé par diverses définitions (j'ai mis une explication à côté pour que vous puissiez comprendre pourquoi les solutions proposées ci-dessous fonctionnent réellement) qui décident si les types de données correspondants doivent être définis ou non

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

Solutions

Sur la base de la structure du fichier d'en-tête donnée ci-dessus, il existe plusieurs solutions pour cela. Certains pourraient être plus viables tandis que d'autres moins.

  • De toute évidence, vous ne pouvez inclure aucune des définitions de type dans cstdint et stdint.h et vivre avec les définitions de MySql. Cela serait en fait assez limitant car tôt ou tard, un autre en-tête de bibliothèque standard l'inclura et cela pourrait vous obliger à ne pas utiliser la bibliothèque standard du tout, ce qui pourrait être très limitant.

  • Vous pouvez abandonner complètement la chaîne d'outils de construction 32 bits que vous utilisez, passer à un **compilateur 64 bits et compiler pour 64 bits . Dans ce cas, cela ne devrait pas se produire car l'en-tête config.h dans MySql n'est inclus que pour les systèmes 32 bits, comme indiqué ci-dessus ! S'il n'y a aucune bonne raison pour que votre projet soit 32 bits, c'est ce que je ferais réellement. En parlant de votre compilateur :vous semblez utiliser GCC 6.3.0 qui a été publié en 2016 et en fait ne prend pas entièrement en charge le C++17 norme de langue vous lui dites de compiler avec CMAKE_CXX_STANDARD 17 dans votre fichier CMake. Vous voudrez peut-être utiliser un autre compilateur plus récent au cas où vous voudriez utiliser les fonctionnalités C++17 de manière intensive. Sinon C++14 n'est pas trop mal non plus.

  • Vous pouvez utiliser Visual Studio 2010 (version 1600 ) ou version ultérieure pour la compilation, car dans ce cas, l'en-tête inclura automatiquement les définitions de la norme au lieu de définir les siennes.

  • Vous pouvez définir l'indicateur de pré-processeur #define CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES au-dessus de votre code (ou à l'intérieur de l'IDE que vous utilisez pour votre projet) comme si cet indicateur était défini sur config.h le fichier ne définira aucun type de données.

  • De même, vous pouvez également le résoudre en ouvrant MYSQLC~1.0/include/jdbc/cppconn/config.h et modifier les directives du pré-processeur de

    #define HAVE_MS_INT32  1
    #define HAVE_MS_UINT32 1
    

    à

    #define HAVE_MS_INT32  0
    #define HAVE_MS_UINT32 0
    

    Cela désactivera les définitions correspondantes pour tous les programmes que vous écrivez également à l'avenir et qui incluent cet en-tête.

Deuxième problème :lien vers des bibliothèques compilées avec Visual Studio

Le deuxième message d'erreur que vous obtenez est en fait lié à la liaison de la bibliothèque. Sous Windows, les bibliothèques compilées avec différents compilateurs ne sont généralement pas compatibles. Cela signifie qu'un programme compilé avec GCC ne peut pas inclure de bibliothèques compilées avec Visual Studio. Dans votre cas, la DLL a été compilée avec Visual Studio et, par conséquent, la liaison à votre programme GCC échoue.

Comme également mentionné ici vous pouvez forcer CMake à utiliser MinGW au lieu de Visual Studio avec cmake -G "MinGW Makefiles" mais je l'ai essayé et cela ne fonctionne ni avec MariaDB ni MySQL.

Utilisation de MSYS2 dans MySQL, j'obtiens une erreur cryptique liée à OpenSSL sur MariaDB en suivant le guide officiel puis en utilisant

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

Je dois faire quelques modifications manuelles, telles que la modification de /src/CArrayImp.h et changez la ligne 59 en 63 de

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

à

#define ZEROI64 0LL

comme 0I64 est uniquement défini par Visual Studio. De plus, il faut supprimer l'instanciation du modèle dans CArray.cpp mais je me retrouve toujours avec un The system cannot find the path specified. Message d'erreur. De même, je n'ai pas pu le faire compiler dans Cygwin.

Alternatives au connecteur SQL C++

Je n'ai pas de solution pour le dernier problème, mais vous voudrez peut-être jeter un œil à des alternatives. Vous pouvez télécharger SQLite depuis la source et compilez-le. Selon le guide d'installation depuis la source il est compatible avec MinGW mais il est seulement léger . Il en va de même pour le Shareware SQLAPI++ . Selon leur page "Commande" la version d'essai pour Windows est entièrement fonctionnelle

Les deux doivent prendre en charge MySql :par ex. voir ici .

tl;dr : Utilisez les connecteurs MySQL et MariaDB sur Windows dans Visual Studio uniquement . Si vous ne pouvez pas utiliser Visual Studio, jetez un œil aux connecteurs SQL C++ alternatifs tels que SQLite et SQLAPI++ à la place.