И двата конектора MySQL, както и MariaDB (които споделят едно и също наследство ) са предназначени да бъдат компилирани и използвани само с Visual Studio под Windows . В StackOverflow ще намерите много предишни въпроси относно него. Проблемът с тях е, че те дефинират много структури, които вече са дефинирани в стандартната библиотека и след това също се свързват към стандартната библиотека.
Предлагам ви или да преминете към Visual Studio, или към Linux система . Ако трябва да използвате GCC под Windows, потърсете друг конектор. Тези проблеми няма да се решат лесно. Ако е така, решенията е малко вероятно да бъдат преносими и може да не работят с бъдещи версии на двата конектора. Можете да разгледате алтернативите SQLite и SQLAPI++ .
Първи проблем:цели числа с фиксирана ширина
Първият проблем, който споменавате, всъщност е свързан с типове цели числа с фиксирана ширина
и 32-битови операционни системи, дефинирани в заглавните файлове. Има традиционните цели числа като char
, short
, int
, long
и long long
но освен това и гореспоменатите цели числа с фиксирана ширина.
Конекторът MySql дефинира int32_t
тип данни в config.h
а също и стандартната C++ библиотека ги дефинира:MySql дефинира int32_t
с тип данни на компилатора __int32
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
което изненадващо се оказва long int
типове данни
typedef long int int32_t;
typedef long unsigned int uint32_t;
докато стандартната библиотека ги дефинира като обикновен int
typedef int int32_t;
typedef unsigned int uint32_t;
long
целочислени типове данни са гарантирани, че са поне 32-битови :На 32-битова архитектура long int
е 32-битов (точно като int
), докато за 64-битовите имат различни дължини - long int
е 64-битов и е int
е само 32-битов (вижте тук
). Това означава, че всъщност за 32-битова система тези дефиниции трябва да са идентични, но въпреки това компилаторът смята, че са в конфликт.
Заглавката MySql е обвита от различни дефиниции (слагам обяснение до тях, за да можете да разберете защо предложените решения, дадени по-долу, всъщност работят), които решават дали съответните типове данни трябва да бъдат дефинирани или не
// 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
Решения
Въз основа на структурата на заглавния файл, даден по-горе, има няколко решения за това. Някои може да са по-жизнеспособни, докато други по-малко.
-
Ясно е, че не можете да включите дефиниции на типове в
cstdint
иstdint.h
и живейте с MySql дефинициите. Това всъщност би било доста ограничаващо, тъй като рано или късно вероятно друга заглавка на стандартна библиотека ще го включи и това може да доведе до това да ви принуди изобщо да не използвате стандартната библиотека, което може да е много ограничаващо. -
Бихте могли напълно да се откажете от 32-битовата верига от инструменти за компилиране, която използвате, да преминете към **64-битов компилатор и да компилирате за 64-битов . В този случай това не трябва да се случва като заглавката
config.h
в MySql е включен само за 32-битови системи, както е посочено по-горе! Ако няма основателна причина вашият проект да бъде 32-битов, това е, което всъщност бих направил. Говорейки за вашия компилатор:Изглежда, че използвате GCC 6.3.0, който беше пуснат през 2016 г. и всъщност не поддържа напълноC++17
езиков стандарт вие му казвате да компилира сCMAKE_CXX_STANDARD 17
във вашия CMake-файл. Може да искате да използвате друг по-нов компилатор, в случай че искате да използвате широко функциите на C++17. В противен случай C++14 също не е много лош. -
Можете да използвате Visual Studio 2010 (версия
1600
) или по-късно за компилация, тъй като в този случай заглавката автоматично ще включва дефинициите от стандарта, вместо да дефинира свои собствени. -
Можете да дефинирате флага на предпроцесора
#define CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES
върху вашия код (или вътре в IDE, която използвате за вашия проект), сякаш този флаг е зададенconfig.h
файл няма да дефинира никакви типове данни. -
По подобен начин можете също да го разрешите, като отворите
MYSQLC~1.0/include/jdbc/cppconn/config.h
и променете директивите на предпроцесора от#define HAVE_MS_INT32 1 #define HAVE_MS_UINT32 1
до
#define HAVE_MS_INT32 0 #define HAVE_MS_UINT32 0
Това ще деактивира съответните дефиниции за всички програми, които също ще пишете в бъдеще, които включват тази заглавка.
Втори проблем:Свързване към библиотеки, компилирани с Visual Studio
Второто съобщение за грешка, което получавате, всъщност е свързано със свързването на библиотеката. В Windows библиотеките, компилирани с различни компилатори, обикновено не са съвместими. Това означава, че програма, компилирана с GCC, не може да включва библиотеки, компилирани с Visual Studio. Във вашия случай DLL е компилиран с Visual Studio и следователно свързването към вашата GCC програма е неуспешно.
Както също беше споменато тук
можете да принудите CMake да използва MinGW вместо Visual Studio с cmake -G "MinGW Makefiles"
но го пробвах и не работи нито с MariaDB, нито с MySQL.
Използване на MSYS2 в MySQL получавам загадъчна грешка, свързана с OpenSSL, докато съм в MariaDB след официално ръководство и след това с помощта на
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -G "MinGW Makefiles" -DCONC_WITH_UNIT_TESTS=Off -DCONC_WITH_MSI=OFF -DWITH_SSL=SCHANNEL .
cmake --build . --config RelWithDebInfo
Трябва да направя няколко ръчни модификации, като например промяна на /src/CArrayImp.h
и променете ред 59 на 63 от
#ifndef _WIN32
# define ZEROI64 0LL
#else
# define ZEROI64 0I64
#endif
до
#define ZEROI64 0LL
като 0I64
се дефинира само от Visual Studio. Освен това трябва да се премахне инстанцията на шаблона в CArray.cpp
но все пак получавам The system cannot find the path specified.
съобщение за грешка. По същия начин не успях да го накарам да се компилира в Cygwin.
Алтернативи за SQL C++ конектор
Нямам решение за последния проблем, но може да искате да разгледате алтернативи. Можете да изтеглите SQLite от източника и го компилирайте. Според ръководството за инсталиране от източник той е съвместим с MinGW, но е само лек . Същото трябва да бъде и Shareware SQLAPI++ . Според тяхната страница „Поръчка“ пробната версия за Windows е напълно функционална
И двете трябва да поддържат MySql:напр. вижте тук .
tl;dr: Използвайте MySQL и MariaDB конекторите в Windows само в Visual Studio . Ако не можете да използвате Visual Studio, разгледайте алтернативните C++ SQL конектори като SQLite и SQLAPI++ вместо това.