Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Thư viện MySQL và MariaDB trong C ++ sử dụng cmake, mingw

Cả hai trình kết nối MySQL cũng như MariaDB ( chia sẻ cùng một di sản ) được dự định chỉ được biên dịch và sử dụng với Visual Studio trên Windows . Bạn sẽ tìm thấy rất nhiều câu hỏi trước đây trên StackOverflow liên quan đến nó. Vấn đề với chúng là chúng xác định rất nhiều cấu trúc đã được xác định trong thư viện chuẩn và sau đó liên kết với cả thư viện chuẩn.

Tôi khuyên bạn nên chuyển sang Visual Studio hoặc sang hệ thống Linux . Nếu bạn phải sử dụng GCC trong Windows thì hãy tìm một trình kết nối khác. Những vấn đề này sẽ không được giải quyết một cách dễ dàng. Nếu vậy, các giải pháp không có khả năng di động và có thể không hoạt động với các phiên bản tương lai của hai trình kết nối. Bạn có thể xem qua lựa chọn thay thế SQLite SQLAPI ++ .

Vấn đề đầu tiên:số nguyên có độ rộng cố định

Vấn đề đầu tiên bạn đề cập thực sự liên quan đến các loại số nguyên có chiều rộng cố định và hệ điều hành 32 bit được xác định trong tệp tiêu đề. Có các kiểu số nguyên truyền thống như char , short , int , longlong long mà còn là các số nguyên có chiều rộng cố định đã nói ở trên.

Trình kết nối MySql xác định int32_t kiểu dữ liệu trong config.h và thư viện C ++ chuẩn cũng định nghĩa chúng:MySql định nghĩa int32_t với kiểu dữ liệu trình biên dịch __int32

typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;

điều đáng ngạc nhiên hóa ra lại là long int kiểu dữ liệu

typedef long int int32_t;
typedef long unsigned int uint32_t;

trong khi thư viện chuẩn đang xác định chúng là int thông thường

typedef int int32_t;
typedef unsigned int uint32_t;

long kiểu dữ liệu số nguyên được đảm bảo ít nhất là 32 bit :Trên kiến ​​trúc 32 bit, một long int là 32-bit (giống như một int ) trong khi đối với 64-bit, chúng có độ dài khác nhau - a long int là 64-bit và một int chỉ là 32 bit (xem tại đây ). Điều này có nghĩa là thực sự đối với hệ thống 32 bit, các định nghĩa này phải giống hệt nhau nhưng trình biên dịch cho rằng chúng mâu thuẫn với nhau.

Tiêu đề MySql được bao bọc bởi nhiều định nghĩa khác nhau (tôi đặt một giải thích bên cạnh chúng để bạn có thể hiểu tại sao các giải pháp được đề xuất đưa ra bên dưới thực sự hoạt động) quyết định xem loại dữ liệu tương ứng có nên được xác định hay không

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

Giải pháp

Dựa trên cấu trúc của tệp tiêu đề được đưa ra ở trên, có một số giải pháp cho việc này. Một số có thể khả thi hơn trong khi những người khác ít hơn.

  • Rõ ràng là bạn không thể không bao gồm bất kỳ định nghĩa loại nào trong cstdintstdint.h và sống với các định nghĩa MySql. Điều này thực sự sẽ khá hạn chế vì sớm hay muộn thì một tiêu đề thư viện tiêu chuẩn khác sẽ bao gồm nó và nó có thể dẫn đến việc buộc bạn hoàn toàn không sử dụng thư viện tiêu chuẩn. Điều này có thể rất hạn chế.

  • Bạn có thể từ bỏ hoàn toàn chuỗi công cụ xây dựng 32 bit mà bạn đang sử dụng, chuyển sang trình biên dịch ** 64 bit và biên dịch cho 64 bit . Trong trường hợp này, điều này sẽ không xảy ra dưới dạng tiêu đề config.h trong MySql chỉ được bao gồm cho các hệ thống 32-bit như đã nêu ở trên! Nếu không có lý do chính đáng nào khiến dự án của bạn phải là 32-bit thì đó là điều tôi thực sự sẽ làm. Nói về trình biên dịch của bạn:Có vẻ như bạn đang sử dụng GCC 6.3.0 được phát hành vào năm 2016 và thực tế là không hỗ trợ đầy đủ C++17 tiêu chuẩn ngôn ngữ bạn đang yêu cầu nó biên dịch với CMAKE_CXX_STANDARD 17 trong tệp CMake của bạn. Bạn có thể muốn sử dụng một trình biên dịch khác mới hơn trong trường hợp bạn muốn sử dụng rộng rãi các tính năng của C ++ 17. Nếu không thì C ++ 14 cũng không quá tệ.

  • Bạn có thể sử dụng Visual Studio 2010 (phiên bản 1600 ) trở lên để biên dịch như trong trường hợp này, tiêu đề sẽ tự động bao gồm các định nghĩa từ tiêu chuẩn thay vì xác định các định nghĩa của chính nó.

  • Bạn có thể xác định cờ của bộ xử lý trước #define CPPCONN_DONT_TYPEDEF_MS_TYPES_TO_C99_TYPES trên đầu mã của bạn (hoặc bên trong IDE bạn đang sử dụng cho dự án của mình) như thể cờ này được đặt config.h tệp sẽ không xác định bất kỳ kiểu dữ liệu nào.

  • Tương tự, bạn cũng có thể giải quyết nó bằng cách mở MYSQLC~1.0/include/jdbc/cppconn/config.h sửa đổi các chỉ thị của bộ xử lý trước từ

    #define HAVE_MS_INT32  1
    #define HAVE_MS_UINT32 1
    

    đến

    #define HAVE_MS_INT32  0
    #define HAVE_MS_UINT32 0
    

    Thao tác này sẽ hủy kích hoạt các định nghĩa tương ứng cho tất cả các chương trình bạn đang viết trong tương lai có bao gồm tiêu đề này.

Vấn đề thứ hai:Liên kết với các thư viện được biên dịch bằng Visual Studio

Thông báo lỗi thứ hai mà bạn nhận được thực sự liên quan đến việc liên kết thư viện. Trên Windows, các thư viện được biên dịch bằng các trình biên dịch khác nhau thường không tương thích. Điều này có nghĩa là một chương trình được biên dịch bằng GCC không thể bao gồm các thư viện được biên dịch bằng Visual Studio. Trong trường hợp của bạn, DLL được biên dịch bằng Visual Studio và do đó việc liên kết với chương trình GCC của bạn không thành công.

Như cũng đã đề cập tại đây bạn có thể buộc CMake sử dụng MinGW thay vì Visual Studio bằng cmake -G "MinGW Makefiles" nhưng tôi đã thử nó và nó không hoạt động với MariaDB hay MySQL.

Sử dụng MSYS2 trong MySQL, tôi gặp một lỗi khó hiểu liên quan đến OpenSSL khi ở trên MariaDB sau hướng dẫn chính thức và sau đó sử dụng

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

Tôi phải thực hiện một số sửa đổi thủ công, chẳng hạn như sửa đổi /src/CArrayImp.h và thay đổi dòng 59 thành 63 từ

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

đến

#define ZEROI64 0LL

dưới dạng 0I64 chỉ được định nghĩa bởi Visual Studio. Hơn nữa, người ta phải xóa phần khởi tạo mẫu trong CArray.cpp nhưng tôi vẫn gặp phải The system cannot find the path specified. thông báo lỗi. Tương tự, tôi không thể biên dịch nó trong Cygwin.

Các lựa chọn thay thế trình kết nối SQL C ++

Tôi không có giải pháp nào cho vấn đề cuối cùng nhưng bạn có thể muốn xem các giải pháp thay thế. Bạn có thể tải xuống SQLite từ nguồn và biên dịch nó. Theo hướng dẫn cài đặt từ nguồn nó tương thích với MinGW nhưng nó chỉ nhẹ . Vì vậy, nên là Shareware SQLAPI ++ . Theo trang "Đặt hàng" của họ phiên bản dùng thử cho Windows có đầy đủ chức năng

Cả hai đều phải hỗ trợ MySql:ví dụ:xem tại đây .

tl; dr: Sử dụng trình kết nối MySQL và MariaDB trên Chỉ Windows trong Visual Studio . Nếu bạn không thể sử dụng Visual Studio, hãy xem trình kết nối SQL C ++ thay thế SQLite SQLAPI ++ thay vào đó.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tích hợp MySQL với Python trong Windows

  2. MySQL NET Connect 6.7.2 trong Visual Studio 2012

  3. Cách lặp lại các câu lệnh print trong khi thực thi một script sql

  4. tự động cập nhật hàng sau một thời gian nhất định

  5. Đối tượng không thể được chuyển đổi thành một chuỗi trong MySQLi PHP