Mysql
 sql >> база данни >  >> RDS >> Mysql

Библиотеките на MySQL и MariaDB в C++, използвайки cmake, mingw

И двата конектора 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++ вместо това.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Минус оператор, който ми дава грешки в mysql

  2. може ли да се изпълни по-бързо с голямо количество данни [MySQL]

  3. изберете опция за актуализиране на втората опция за избор въз основа на попълнените от mysql падащи менюта

  4. Как (MySQL) да умножаваме колони и след това редовете за сума?

  5. Колко реално място за съхранение се използва с декларация varchar(100) в mysql?