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
etstdint.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 leC++17
norme de langue vous lui dites de compiler avecCMAKE_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 surconfig.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.