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 và 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
, long
và long 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
cstdint
vàstdint.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ớiCMAKE_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 đặtconfig.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
và 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 và SQLAPI ++ thay vào đó.