Tanto los conectores MySQL como MariaDB (que comparten la misma herencia ) están diseñados para ser compilados y utilizados con Visual Studio solo en Windows . Encontrará muchas preguntas anteriores sobre StackOverflow al respecto. El problema con ellos es que definen muchas estructuras que ya están definidas en la biblioteca estándar y luego también se vinculan a la biblioteca estándar.
Le sugiero que cambie a Visual Studio o a un sistema Linux . Si tiene que usar GCC en Windows, busque otro conector. Estos problemas no se resolverán fácilmente. Si es así, es poco probable que las soluciones sean portátiles y es posible que no funcionen con futuras versiones de los dos conectores. Puede echar un vistazo a las alternativas SQLite y SQLAPI++ .
Primer problema:enteros de ancho fijo
El primer problema que mencionas en realidad está relacionado con los tipos enteros de ancho fijo
y sistemas operativos de 32 bits definidos en los archivos de encabezado. Existen los tipos enteros tradicionales como char
, short
, int
, long
y long long
pero además los enteros de ancho fijo antes mencionados.
El Conector MySql define el int32_t
tipo de datos en config.h
y también la biblioteca estándar de C++ los define:MySql define el int32_t
con el tipo de datos del compilador __int32
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
que sorprendentemente resulta ser el long int
tipos de datos
typedef long int int32_t;
typedef long unsigned int uint32_t;
mientras que la biblioteca estándar los define como int
regulares
typedef int int32_t;
typedef unsigned int uint32_t;
long
tipos de datos enteros están garantizados para ser de al menos 32 bits :En una arquitectura de 32 bits, un long int
es de 32 bits (al igual que un int
) mientras que para 64 bits tienen diferentes longitudes:un long int
es de 64 bits y un int
es solo de 32 bits (ver aquí
). Esto significa que, en realidad, para un sistema de 32 bits, estas definiciones deberían ser idénticas pero, sin embargo, el compilador cree que están en conflicto.
El encabezado MySql está envuelto por varias definiciones (puse una explicación junto a ellas para que pueda entender por qué las soluciones propuestas que se dan a continuación realmente funcionan) que deciden si los tipos de datos correspondientes deben definirse o no
// 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
Soluciones
Según la estructura del archivo de encabezado anterior, hay un par de soluciones para esto. Algunos pueden ser más viables mientras que otros menos.
-
Claramente, podría no incluir ninguna de las definiciones de tipo en
cstdint
ystdint.h
y vive con las definiciones de MySql. En realidad, esto sería bastante limitante, ya que tarde o temprano es probable que otro encabezado de biblioteca estándar lo incluya y podría obligarlo a no usar la biblioteca estándar en absoluto, lo que podría ser muy limitante. -
Podría abandonar por completo la cadena de herramientas de compilación de 32 bits que está utilizando, cambiar a un **compilador de 64 bits y compilar para 64 bits . En este caso esto no debería suceder ya que el encabezado
config.h
en MySql solo se incluye para sistemas de 32 bits como se indicó anteriormente. Si no hay una buena razón para que su proyecto sea de 32 bits, eso es lo que realmente haría. Hablando de su compilador:parece que está usando GCC 6.3.0, que se lanzó en 2016 y en realidad no es completamente compatible conC++17
estándar de idioma le estás diciendo que compile conCMAKE_CXX_STANDARD 17
en su archivo CMake. Es posible que desee usar otro compilador más nuevo en caso de que quiera usar las funciones de C++ 17 de forma extensiva. De lo contrario, C++14 tampoco es tan malo. -
Podrías usar Visual Studio 2010 (versión
1600
) o posterior para la compilación ya que en este caso el encabezado incluirá automáticamente las definiciones del estándar en lugar de definir las suyas propias. -
Podrías definir el indicador de preprocesador
#define CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES
encima de su código (o dentro del IDE que está utilizando para su proyecto) como si este indicador estuviera configurado enconfig.h
el archivo no definirá ningún tipo de datos. -
Del mismo modo, también podría resolverlo abriendo
MYSQLC~1.0/include/jdbc/cppconn/config.h
y modificar las directivas del preprocesador de#define HAVE_MS_INT32 1 #define HAVE_MS_UINT32 1
a
#define HAVE_MS_INT32 0 #define HAVE_MS_UINT32 0
Esto desactivará las definiciones correspondientes para todos los programas que también esté escribiendo en el futuro que incluyan este encabezado.
Segundo problema:vinculación a bibliotecas compiladas con Visual Studio
El segundo mensaje de error que recibe en realidad está relacionado con la vinculación de la biblioteca. En Windows, las bibliotecas compiladas con diferentes compiladores generalmente no son compatibles. Esto significa que un programa compilado con GCC no puede incluir bibliotecas compiladas con Visual Studio. En su caso, la DLL se compiló con Visual Studio y, por lo tanto, falla la vinculación a su programa GCC.
Como también se menciona aquí
puede obligar a CMake a usar MinGW en lugar de Visual Studio con cmake -G "MinGW Makefiles"
pero lo he probado y no funciona ni con MariaDB ni con MySQL.
Usando MSYS2 en MySQL obtengo un error críptico relacionado con OpenSSL mientras estoy en MariaDB siguiendo el guía oficial y luego usando
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -G "MinGW Makefiles" -DCONC_WITH_UNIT_TESTS=Off -DCONC_WITH_MSI=OFF -DWITH_SSL=SCHANNEL .
cmake --build . --config RelWithDebInfo
Tengo que hacer un par de modificaciones manuales, como modificar /src/CArrayImp.h
y cambia la línea 59 a la 63 de
#ifndef _WIN32
# define ZEROI64 0LL
#else
# define ZEROI64 0I64
#endif
a
#define ZEROI64 0LL
como 0I64
solo lo define Visual Studio. Además, se debe eliminar la instanciación de la plantilla en CArray.cpp
pero todavía termino con un The system cannot find the path specified.
mensaje de error. Del mismo modo, no pude compilarlo en Cygwin.
Alternativas al conector SQL C++
No tengo solución para el último problema, pero es posible que desee echar un vistazo a las alternativas. Puede descargar SQLite de la fuente y compilarlo. De acuerdo con la guía de instalación de la fuente es compatible con MinGW pero solo es ligero . Así debería ser Shareware SQLAPI++ . Según su página de "Pedido" la versión de prueba para Windows es completamente funcional
Ambos deben ser compatibles con MySql:p. ver aquí .
tl;dr: Use los conectores MySQL y MariaDB en Windows en Visual Studio solamente . Si no puede usar Visual Studio, eche un vistazo a los conectores SQL de C++ alternativos como SQLite y SQLAPI++ en su lugar.