尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

VS2013下源码编译MySQL Connector/C++完整指南

VS2013下源码编译MySQL Connector/C++完整指南 简介面向在视窗操作系统上使用微软Visual Studio 2013开发环境的C程序员这份资源是MySQL官方连接器在三十二位与六十四位平台下的完整编译成果同时附带了示例工程用于解决自行编译过程中常见的依赖库缺失、头文件路径错误以及链接配置复杂等问题。资源包共收录六十三个文件压缩后大小约二十四点九八兆字节其中包含二十一个头文件、二十个静态库或导入库、九个动态链接库、两个C源文件以及项目解决方案、工程配置和调试符号文件等并按调试版本、发布版本和三十二位、六十四位分类存放便于按需选用。示例代码从创建驱动实例开始依次演示了建立连接、执行SQL语句、遍历结果集以及关闭资源等关键步骤同时提供了异常处理的思路可作为编写数据库操作模块的参考模板。目前已有五百一十人学习使用解压后只需配置好头文件包含路径和附加依赖项即可快速集成到自己的项目中显著缩短开发周期。 前一阵子帮朋友处理一个老项目的迁移从32位升级到64位代码本身没费什么劲反而卡在最不起眼的一环——MySQL Connector/C 的动态库对不上。他开发机装的是VS2013而官方预编译包里的Connector/C 8.x是用VS2015/2017编译的直接把lib塞进工程链接阶段就开始报LNK2038、LNK2019头大。最后只能亲自动手用VS2013从源码编译一套匹配的MySQL Connector/C顺便把win32和win64两份都出了。今天把整个流程完整复盘一下包括版本选型、CMake配置、编译步骤、部署细节以及一段可以直接跑通的示例代码专门写给还在维护VS2013老项目的同行。如果你也在被第三方库版本不匹配折磨这篇文章应该能帮你省下至少一个下午的时间。1. 为什么放着官方包不用非要自己编译1.1 官方二进制包的“版本陷阱”MySQL官方提供的Connector/C预编译二进制包通常是用当前较新的MSVC版本编译的比如VS2015、VS2017甚至VS2019。这在绝大多数场景下没问题因为大家基本跟随新工具链走。但VS2013这个版本比较特殊它的C运行库是msvcr120.dll编译器生成的MSC_VER是1800而VS2015对应1900、VS2017对应1910以上。MSVC在VS2015之后对C标准库做了大量ABI调整前后版本编译出来的库混着链接轻则链接报错重则运行期莫名崩溃。说白了C/C的库不像Java的jar包那样“一次编译到处运行”它与编译器版本、运行库版本、甚至Debug/Release模式强绑。你在VS2013里链接一个VS2017编译出来的MySQL Connector/C库就像把带国标插头的设备怼进英标插座——接口长得像实际上不通。官方包默认用新工具链编译这决定了很多老版本IDE用户必须走“自行编译”这条路。1.2 老项目有自己的“脾气”工具链锁定很多传统企业里的老项目尤其是工控、银行、制造业内部系统开发环境说锁死就锁死。VS2013在这个圈子里渗透率极高因为项目里可能还依赖了某些只能在VS2013下正常编译的ActiveX控件、第三方MFC库或者干脆是公司IT策略不允许换IDE。这时候你不可能因为一个连接库去升级整个工具链只能让第三方依赖去适配IDE。所以这里的核心思路是连接库自编译平台工具集固定为Visual Studio 2013v120用和项目一致的方式产出库文件。另外还有一个隐性好处自己编译可以自主控制是否使用静态运行时库/MT、/MTd。如果采用静态链接部署时不需要目标机器安装VS2013运行库也不用拷一堆msvcr120.dll专治各种“装到客户机器上跑不起来”的疑难杂症。这个选项在官方预编译包里是没法自由切换的。2. 编译前的准备版本选型与依赖下载2.1 版本对照表不是越新越好刚开始我也踩过“拿最新版连接器源码编译”的坑。MySQL Connector/C 8.0.x虽然也支持CMake配置但它的API和1.1.x完全是两代人而且对CMake版本、Boost版本的要求都比较挑剔在VS2013上编译经常报“语法不兼容”。试了一圈之后我锁定了1.1.x系列这在老项目里是最稳的选择。具体推荐版本见下表依赖项推荐版本说明MySQL Connector/C1.1.6 或 1.1.x 最新API简单兼容VS2013不需要额外安装C Connector库Boost1.59.0连接器编译时只依赖Boost头文件1.59完全够用OpenSSL不需要可禁用如果不做SSL加密连接CMake里直接关掉CMake3.15.5支持VS2013生成器操作界面也顺手MySQL Server5.7 / 8.0用于最终测试连接版本不影响编译这里最需要留意的是Boost。Connector/C 1.1.x在CMake配置阶段会强制检查Boost头文件没配好直接报错。不过它只是用到Boost的智能指针、线程相关头文件不需要把Boost整个编译一遍所以准备一份解压后的Boost源码目录就够了。2.2 目录规划和下载注意事项建议把所有源码下载到一个纯英文路径下比如D:\dev\src不要放桌面、不要带中文和空格。目录带空格虽然大多数时候没事但在CMake和VS2013搭配时偶尔会触发一些诡异错误不值得冒险。下载MySQL Connector/C源码时务必选“Source Code”ZIP包不要去下二进制包。Boost直接去官方或镜像站下载boost_1_59_0.zip解压即可。CMake在3.15左右对VS2013生成器的支持都很稳定我用3.15.5跑完整个流程没有任何问题装的时候记得勾选“Add CMake to system PATH”。3. 完整编译流程从CMake配置到库文件落地3.1 CMake配置项逐个解释打开CMake GUI之后第一行填源码路径比如D:/dev/src/mysql-connector-cpp-1.1.6第二行填构建路径我习惯在源码目录外单独建一个build目录比如D:/dev/build/connector-vs2013-x64。第一次点Configure时会弹出生成器选择窗口这时需要根据目标平台选择编译win3232位选择“Visual Studio 12 2013”编译win6464位选择“Visual Studio 12 2013 Win64”选择完成后CMake会进行第一轮探测几乎必然会在红色报错区域提示找不到依赖。此时在变量列表里配置以下几个关键项变量名取值作用CMAKE_INSTALL_PREFIXD:/dev/dist/connector-x64最终安装路径头文件、库文件都会集中到这里WITH_BOOSTD:/dev/src/boost_1_59_0Boost源码解压后的根目录WITH_SSL0关闭SSL依赖不做加密连接时强烈建议设为0DYNAMIC_LIB1编译动态库生成DLL导入库设为0则编译静态库这几个变量里最容易出坑的是WITH_SSL。Connector/C 1.1.x在默认情况下会尝试寻找OpenSSL如果你机器上恰好没有配置好的OpenSSL开发库又不主动关掉Configure阶段会一直卡在“找不到OpenSSL”的红字上。实测如果应用走内网、不需要SSL加密连接完全可以直接设为0省掉一整条依赖链。3.2 生成工程并执行编译确认所有变量配置完成后再次点击Configure直到红色报错消失。然后点GenerateCMake会在构建目录下生成一个MySQL_Connector.sln具体名称随版本略有差异。用VS2013打开这个解决方案先在工具栏的解决方案配置里选好Release然后在“配置管理器”里核对活动解决方案平台——如果是64位编译这里应该显示x64如果是win32则显示Win32。接下来右键“ALL_BUILD”项目选择“生成”。整个编译过程大概5到10分钟视机器性能而定。编译完成后在构建目录下的lib\Release里能看到产物动态库模式mysqlcppconn.dll、mysqlcppconn.libDebug模式会多一个带d后缀的版本比如mysqlcppconn-d.lib静态库模式mysqlcppconn-static.lib顺带提一句编译64位版本时输出目录通常在x64\Release下而32位版本直接在Release下找文件的时候别走错目录。3.3 Install步骤让产物集中管理每次编译完都在build目录里翻文件比较零散。我的习惯是在VS2013里再生成一次“INSTALL”项目它会把头文件、库文件、DLL按目录结构复制到CMAKE_INSTALL_PREFIX指定的位置。这样后续给多个工程引用时只需配置一个统一路径升级版本时替换整个目录即可。安装完成后D:\dev\dist\connector-x64下会看到include、lib、bin三个子目录结构清爽拷贝给别人用也方便。3.4 win32和win64差异处理如果你和一样需要同时产出32位和64位两套库建议分两个构建目录跑两次CMake比如build-vs2013-win32和build-vs2013-x64。第二次Configure时注意换生成器别用同一目录否则CMake的缓存会串。两份库编译完成后把安装目录分别命名为connector-win32、connector-x64后续在工程里按目标平台切换引用即可。4. 示例代码与VS2013工程配置4.1 建表与示例代码假设MySQL里已经有一个测试库test_db里面有一张users表结构很简单id自增主键、name为用户名。示例代码要做的事情就是建立连接、执行一条查询、遍历结果集并打印。CREATE DATABASE IF NOT EXISTS test_db DEFAULT CHARACTER SET utf8mb4; USE test_db; CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(64) NOT NULL ); INSERT INTO users (name) VALUES (Alice), (Bob), (Charlie);接下来是C代码我尽量把异常处理和资源管理写得贴近实际生产可用而不是玩具代码#include iostream #include memory #include mysql_connection.h #include mysql_driver.h #include cppconn/statement.h #include cppconn/resultset.h #include cppconn/exception.h int main() { try { sql::mysql::MySQL_Driver* driver sql::mysql::get_mysql_driver_instance(); std::unique_ptrsql::Connection conn( driver-connect(tcp://127.0.0.1:3306, root, your_password)); conn-setSchema(test_db); conn-setSessionVariable(character_set_results, utf8mb4); std::unique_ptrsql::Statement stmt(conn-createStatement()); std::unique_ptrsql::ResultSet res( stmt-executeQuery(SELECT id, name FROM users ORDER BY id)); while (res-next()) { std::cout id res-getInt(id) , name res-getString(name) std::endl; } } catch (sql::SQLException e) { std::cerr SQL ERROR: e.what() , code e.getErrorCode() std::endl; return 1; } return 0; }4.2 工程引用配置在VS2013里新建一个空的控制台工程然后在“项目属性”里做四件事C/C - 常规 - 附加包含目录填入安装目录的include路径比如D:\dev\dist\connector-x64\include链接器 - 常规 - 附加库目录填入安装目录的lib路径链接器 - 输入 - 附加依赖项手动加上mysqlcppconn.lib如果编译的是Debug模式注意文件名可能是mysqlcppconn-d.lib配置管理器里确认平台是x64或Win32必须和库的位数一致。这里必须强调Debug和Release不能混用。VS2013里Debug和Release的运行时库不同连Debug版本的库时如果工程是Release模式链接器会报“LNK2038 mismatch detected”措辞是运行时库不匹配实际就是Debug/Release串了。4.3 运行部署阶段的DLL处理以动态库模式编译时程序运行需要mysqlcppconn.dll最简单的办法是把它复制到exe同目录下。我试过把它加入系统PATH也能跑但部署到客户机器时不如直接放exe同目录省事。另外如果你的安装包工具支持可以把DLL放到和exe同目录然后设置“安装目录/应用程序目录”优先搜索路径这样更规范。如果编译时选的是静态库DYNAMIC_LIB0那就不需要带DLL但前提是项目里所有模块的运行库设置一致比如统一使用“多线程调试(/MTd)”或“多线程(/MT)”。静态模式下若混用/MT和/MD同样会撞LNK2038。5. 常见问题与排查技巧实录5.1 CMake与编译期高频报错我整理了这次编译及后续帮别人处理时遇到频率最高的几个问题直接做成了速查表报错现场原因分析解决办法提示找不到BoostWITH_BOOST路径没配或路径指到了Boost内部层目录确认路径指向包含boost文件夹的根目录例如boost_1_59_0提示找不到OpenSSL机器上没有配置OpenSSL开发库用不到SSL加密时把WITH_SSL设为0fatal error C1083: 无法打开包括文件: openssl/ssl.h上一条的衍生问题同上或者配合WITH_SSL的OpenSSL根目录LNK2019 unresolved external symbol库没链接、位数不匹配、Debug/Release混用检查附加依赖项核对库名称及平台LNK2038 runtime library mismatch运行库不一致统一/MT或/MD注意Debug/Release对称运行提示找不到mysqlcppconn.dll动态库没有被放到加载路径将DLL放入exe同目录或加入PATH其中LNK2038这个错值得展开说一下。它本质上是MSVC在链接新版标准库代码时插入的版本标记检测用来防止“C标准库实现不一致”的二进制混用。VS2013的MSC_VER是1800VS2015是1900两者编译出的库文件在静态变量布局上可能就不一致强行链接轻则报警重则崩溃。自编译连接器本质上就是保证“链接双方编译环境同源”所以才需要在VS2013里从源码走一趟。5.2 连接MySQL时的认证与字符集坑库编译好了程序也编过了运行阶段同样有经典坑。最典型的是连接MySQL 8.0时用户认证插件默认是caching_sha2_password而Connector/C 1.1.x年代太早不认识这个认证方式会直接报“Authentication plugin caching_sha2_password cannot be loaded”。解决办法有两个一个是把MySQL用户的认证方式改回mysql_native_password在MySQL里执行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY your_password;另一个是换用新版连接器。在老项目锁定VS2013的前提下我一般建议用第一种简单直接。字符集问题也容易踩。连接之后插入或查询中文乱码十有八九是会话字符集没指定。在示例代码里我加了一行setSessionVariable(character_set_results, utf8mb4)这是比较稳妥的做法也可以在连接后直接执行SET NAMES utf8mb4效果一样。注意MySQL的字符集名称是utf8mb4不是utf8不少人在这个细节上翻车。5.3 双平台编译的“缓存陷阱”如果同时编译win32和win64两套库务必分两个构建目录千万不要偷懒在同一个目录里反复切换生成器。CMake的缓存CMakeCache.txt只要生成过就记住了第一轮的生成器类型和变量值第二次就算你在GUI里改了生成器也有很多配置项不会真正刷新。我一开始图省事在同一个build目录里来回切结果64位的库文件里混入了32位的链接参数导致例程链接时一直报无法解析的外部符号白白折腾了两小时。类似地如果你改了WITH_BOOST或WITH_SSL保险起见也可以删掉构建目录重新ConfigureCMake有时候并不像你想象的那么智能。6. 实测中的一点个人体会这次在VS2013下编译MySQL Connector/C整体思路其实可以抽象成一句话老工具链的项目第三方依赖库最可靠的来源永远是“和你同一环境现编出来的”。网上能找到各种编译好的版本但MSVC版本的兼容性玄学太多编译器之间的ABI裂缝是你无法通过改代码绕过去的。自己走一遍CMake流程反而能把工具链版本、运行时库、依赖关系全部理清楚后面再遇到其他C/C库的适配问题也都是同一个套路。最后再分享一个实用小技巧编译完成的库文件建议连同include目录、dll一起打包成一个压缩包按“连接器版本-平台-编译时间”命名比如mysql_connector_cpp_1.1.6_vs2013_x64_20231215.zip。这个习惯帮我解决了很多次“两个月后重新搭环境”的麻烦比临时翻源码再编译一遍省事太多。本文还有配套的精品资源点击获取
返回列表