news 2026/10/27 17:05:05

Delphi 连 MySQL 5.7 驱动 DLL 配置排错

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Delphi 连 MySQL 5.7 驱动 DLL 配置排错

简介:面向仍在使用 Delphi 7 与 dbExpress 访问 MySQL 5.7 的开发者,这份压缩包提供经过项目实测的 libmysql.dll、dbxopenmysql50.dll 两个关键动态库及配套连接示例,重点解决网上版本杂乱、下载后难以正常连通数据库的问题。包内共 17 个文件,整体约 1.3MB,包含 dll 动态库、pas 与 dpr 源码、dfm 窗体、sql 脚本、dcu 编译单元、exe 演示程序以及 docx 配置说明等,既覆盖 TSQLConnection 可视化配置过程,也保留了可直接运行的测试工程。示例还专门演示如何区分数据库字段为 NULL 还是空字符串,并验证程序在 Windows XP 与 Windows 10 下的运行情况;发布时只需携带 libmysql、dbxopenmysql50 等三个运行库即可。包内另附 SQL 建表脚本与窗体设计文件,便于对照阅读源码结构、复现连接过程,也能作为二次开发的基础工程。已有 827 人学习下载,适合需要快速排查 Delphi 连接 MySQL 5.7 环境配置、动态库匹配与字段判空问题,以及处理旧版本兼容性调试的开发者参考。

1. 一个下午踩两次坑:Delphi 连 MySQL 5.7 到底缺哪两个文件

上周帮人收拾一台要重装的上位机。程序是早年用 Delphi 写的,数据库迁到了 MySQL 5.7,程序拷过去一点开就弹框:Unable to load dbxopenmysql50.dll (error code 126)。把 dll 找齐塞进去,报错换成了Cannot load vendor library [libmysql.dll]。两个文件、两个报错,来回折腾了一下午。

这套组合在维护老项目的圈子里太常见了:Delphi 的 dbExpress 本身不认识 MySQL,得靠额外的驱动 dll(dbxopenmysql50.dll)去桥接 MySQL 的客户端库(libmysql.dll),两个文件都不在安装包里,得单独凑。位数、版本、目录三样有一样对不上,程序就是起不来。这篇按我自己重装环境的顺序写:先对版本,再放文件,再填参数,最后验证——照着走能省掉那个下午。

2. 装前对齐版本:Delphi 位数、MySQL 5.7 和两个 dll 的匹配

动手拷文件之前,有三件事必须先确认清楚:宿主进程是几位、驱动 dll 是几位、客户端库是几位。这三者错一个,后面所有配置都是白费。

2.1 先确定 exe 是 32 位还是 64 位

dbExpress 是进程内加载 dll,dll 的位数必须和宿主进程完全一致,跟操作系统是几位没有关系。64 位的 Windows 上跑一个 32 位的 Delphi 程序,它要的是 32 位的 libmysql.dll,你给它一个 64 位的,加载阶段就直接失败。

判断方法有好几种,我习惯用dumpbin看 PE 头:

# 在 VS 开发者命令提示符里执行,或把 dumpbin 所在目录加进 PATH dumpbin /headers YourApp.exe | findstr /i "machine" # machine (x86) -> 32 位进程,必须配 32 位的 libmysql.dll 和 dbxopenmysql50.dll # machine (x64) -> 64 位进程,两个 dll 都要换 64 位版本

/headers读的是 PE 文件头,findstr只筛出机器类型那一行,输出干净。机器上没有 Visual Studio 的话,任务管理器里看进程名后面有没有(32 位)标记,或者用 Process Explorer 看进程属性里的 Image 类型,结论一样。

提示:判断依据永远是宿主进程的位数,不是服务器。MySQL 服务端装的是 64 位版本,你的 32 位客户端程序照样只能用 32 位的 libmysql.dll,这两件事互不影响。

2.2 dbxopenmysql50.dll 在这条链路的什么位置

把调用链摊开看,缺文件时报错为什么会变来变去就清楚了:

TSQLConnection→ dbExpress 核心 →dbxopenmysql50.dll→libmysql.dll→ TCP 3306 → mysqld

Delphi 自带的 dbExpress 只覆盖少数几种数据库,MySQL 不在其中。dbxopenmysql50.dll就是补上的这一层驱动,它把 dbExpress 定义的接口翻译成 libmysql 的 C API 调用。libmysql.dll则是 MySQL 官方客户端库,负责真正的协议握手和数据收发。

所以两个文件缺一不可,缺的位置不同,报错也不同:少了驱动 dll,Delphi 在DriverName这一层就找不到对应的驱动,报的是Unable to load dbxopenmysql50.dll;驱动加载成功但客户端库没到位,报的是Cannot load vendor library。看到哪一句,就知道该查哪一层,不用瞎猜。

至于文件名里的50,通常理解成它对着某一代客户端库接口做的适配。实际以随包说明为准,别拿它去硬配 MySQL 8.0 的 libmysql.dll,认证插件那一关过不去。

2.3 两个 dll 与运行环境的匹配对照

运行场景宿主进程libmysql.dlldbxopenmysql50.dll说明
老项目默认编译32 位5.7 系列 x86 版32 位最常见,两个都是 32 位
新工程改过目标平台64 位5.7 系列 x64 版64 位两个必须同时换,不能一 32 一 64
同一台机器跑两套程序混合分目录各放一份分目录各放一份别往系统目录里塞,会互相踩
服务端升到 8.032 位仍建议用 5.7 的库32 位账号认证插件要改成服务端兼容的那一种

表格里最后一行是血泪经验:服务端升到 8.0 之后,账号默认的认证方式变了,5.7 那一代的客户端库不认识新的握手包,表现是连接直接断开、错误信息还很含糊。要么把该账号的认证方式改回 5.7 认识的那一种,要么整套客户端库和驱动一起升级——后者在老项目里通常动不了,只能走前者。

2.4 落地目录怎么摆

确定好位数,把两个文件和程序放成这个结构,这是最省事、也最好排查的一种:

D:\App\ ├─ YourApp.exe ├─ libmysql.dll ├─ dbxopenmysql50.dll ├─ dbxdrivers.ini (可选,运行期读取) └─ dbxconnections.ini (可选,运行期读取)

放 exe 同目录有两个好处。一是加载优先级,Windows 在默认搜索模式下会先看 exe 所在目录,再往系统目录走,程序一定能找到自己那一份;二是不污染系统,换版本时删掉重拷就行,不用去System32里翻。

dbxdrivers.ini和dbxconnections.ini不是必须的。如果你的代码里是运行时给Params赋值,这两个文件可以直接不放;只有用设计期的连接编辑器、或者希望不同机器改配置不改代码时,才需要它们,写法在第 4 章。

3. 放置与依赖补齐:让进程真的能找到这两个文件

文件拷过去了还是报 126,八成不是位置问题,而是依赖没齐或者拷错了版本。这一章按「放哪 → 缺什么 → 怎么盯」的顺序走一遍。

3.1 首选方案:跟 exe 放一起

大部分情况下,把两个 dll 复制到 exe 同目录就结束了。这一步没什么技术含量,但有两个细节经常被忽略。

第一个是覆盖问题。目标机器上可能已经有一份旧版本的 libmysql.dll 躺在同目录里,复制的时候提示「是否替换」,顺手点了否,程序跑的其实还是旧的。安装前先看一眼目标目录里有没有同名文件,有就先改名备份再拷。

第二个是只读目录。程序装在Program Files下面的时候,普通用户没有写权限,直接拷文件会失败或者被重定向到虚拟存储。这种场景要么用管理员权限装一次,要么把程序整个目录搬到D:\这种不需要提权的位置——后者我更推荐,老项目的安装包经常没处理好权限。

3.2 系统目录方案:什么时候才用,代价是什么

把 dll 丢进C:\Windows\System32(64 位系统上 32 位程序读的是C:\Windows\SysWOW64)也能跑,但我不建议,除非你确实有多个程序要共用同一份客户端库。

代价有三个。一是版本冲突,另一套程序可能要 8.0 的库,覆盖掉之后你这边又崩了,而且崩得莫名其妙。二是排查困难,出问题时很少有人第一时间想到去系统目录翻 dll。三是卸载不干净,删了程序目录,系统目录里那两份还留着,下次装又撞上。

真要走这条路,务必记住 32 位程序读的是SysWOW64而不是System32,这两个目录名字和实际含义是反的,我第一次配的时候就栽在这里。

3.3 error 126 的另一半原因:libmysql.dll 自己还缺依赖

error code 126的字面意思是「找不到指定的模块」,但它不一定指你缺 libmysql.dll,也可能是 libmysql.dll 缺它自己的依赖。MySQL 5.7 的 Windows 客户端库是 VC++ 2013 那一代工具链编出来的,机器上没装对应的运行库,加载一样失败。

# 看 libmysql.dll 自己依赖哪些运行时库 dumpbin /dependents libmysql.dll # 常见会看到 MSVCR120.dll、KERNEL32.dll、WS2_32.dll 之类 # 如果 MSVCR120.dll 在任何目录下都搜不到,就是运行库没装

看到MSVCR120.dll缺失,装一遍对应的 VC++ 运行库即可,这一步在客户机上部署时尤其容易漏。程序在你开发机上好好的,拷到客户机就报 126,九成是这个原因。

注意:运行库要装和 dll 位数一致的那一版。32 位的 libmysql.dll 配 32 位的运行库,装成 64 位的等于没装,报错一模一样。

3.4 用工具盯住加载过程:它到底在找哪个路径

猜不出来的时候别猜,直接看。Process Monitor 加一个过滤器:Process Name is YourApp.exe,再加一条Path contains libmysql,然后启动程序,看输出里标着NAME NOT FOUND的行。

那些行就是进程依次尝试过的路径,从上往下看,最后一条SUCCESS就是它实际加载的位置。如果所有尝试都是NOT FOUND,说明文件确实没在搜索路径里;如果SUCCESS指向了一个你没预期的目录(比如系统目录里的旧版),问题就变成了版本冲突。

这一步花五分钟,能省掉一小时的瞎试。我现在遇到加载类问题基本都先挂上这个过滤器,看一眼就清楚了。

4. 配置 TSQLConnection:dbxopenmysql50 的参数怎么填才生效

文件到位只是让程序能加载驱动,真正连上库还得把TSQLConnection的参数配对。这一章分三块:驱动怎么登记、连接参数怎么给、哪些参数值得调。

4.1 驱动登记:dbxdrivers.ini 里要有这一段

dbExpress 靠一张驱动表来找驱动 dll,这张表存在dbxdrivers.ini里。设计期用的那份一般在 Delphi 安装目录的bin下,运行期读的是 exe 同目录或者用户配置目录下的那一份。不管用哪份,内容长这样:

[Installed Drivers] DbxOpenMySQL50=1 [DbxOpenMySQL50] GetDriverFunc=getSQLDriverMYSQL50 LibraryName=dbxopenmysql50.dll VendorLib=libmysql.dll LibraryNameExp=dbxopenmysql50.dll VendorLibExp=libmysql.dll BlobSize=-1

[Installed Drivers]这一段是注册表,DbxOpenMySQL50=1里的 1 表示启用,改成 0 就等于把这个驱动关掉,有时排查「驱动到底有没有被识别」会用到。

[DbxOpenMySQL50]是驱动自己的配置段,段名就是后面DriverName要填的值。GetDriverFunc是驱动 dll 导出的工厂函数名,写错了会报找不到入口点而不是找不到模块,错误信息完全不同,别搞混。LibraryName和VendorLib分别指向驱动 dll 和客户端库,两个都填文件名、不写路径,让系统按搜索顺序去找。

LibraryNameExp和VendorLibExp是给「显式指定库」的写法留的口子,通常和上面两行一致就行。

4.2 连接参数:两种给法,选一种

设计期给参数,就是在dbxconnections.ini里加一段:

[erp_mysql] DriverName=DbxOpenMySQL50 HostName=127.0.0.1 Database=erpdb User_Name=erp Password=erp_pwd BlobSize=-1 Chartset=utf8

段名erp_mysql就是后面ConnectionName要填的值。这种写法的好处是换机器只改 ini 不动代码,适合交付给运维同事维护的项目。

运行时给参数更可控,也是我现在更常用的方式:

var Conn: TSQLConnection; begin Conn := TSQLConnection.Create(nil); try Conn.DriverName := 'DbxOpenMySQL50'; // 与 dbxdrivers.ini 的段名严格一致 Conn.LibraryName := 'dbxopenmysql50.dll'; // 驱动 dll,按文件名给,别写绝对路径 Conn.VendorLib := 'libmysql.dll'; // 客户端库 Conn.GetDriverFunc := 'getSQLDriverMYSQL50'; // 驱动导出的工厂函数 Conn.LoginPrompt := False; // 关掉登录框,参数不对时直接抛异常 Conn.Params.Clear; Conn.Params.Add('HostName=127.0.0.1'); // 用 IP,别用主机名,省掉一次 DNS 解析 Conn.Params.Add('Database=erpdb'); Conn.Params.Add('User_Name=erp'); Conn.Params.Add('Password=erp_pwd'); Conn.Params.Add('Chartset=utf8'); // 注意拼写,见 4.3 Conn.Params.Add('BlobSize=-1'); // -1 表示按需分配 Conn.Connected := True; // 到这一步才真正发起连接 finally // Conn 的生命周期自己管,别在这里 Free 掉 end; end;

几个参数值得单独说。LoginPrompt := False一定要设,否则参数错了会先弹一个登录框,掩盖掉真正的错误信息,排查时非常误导人。HostName用 IP 而不是机器名,是为了绕开主机名解析,某些内网环境下解析超时会把连接卡住十几秒。Connected := True才是真正建立连接的动作,前面所有赋值都只是准备。

LibraryName和VendorLib写相对文件名就行。写绝对路径的话,换一台机器路径变了又得改代码,反而更麻烦。

4.3 参数取舍:字符集、BlobSize、超时

参数建议值作用与取舍
Chartsetutf8或utf8mb4客户端字符集,拼写就是少个 a,按驱动实际拼写填
BlobSize-1按需分配缓冲,写固定值会让大字段截断
Compress按网络情况内网没必要开,跨机房可以试,CPU 换带宽
ConnectTimeout10左右有的驱动版本根本不认这个键,写了不生效也不报错

字符集这里有个反复出现的坑:参数名的拼写。按标准写法应该是Charset,但这一代驱动里写的是Chartset,少一个 a。填错的时候不会报错,只是不生效,然后你就看到中文变成问号,还以为是数据库那边的问题。我的做法是照驱动实际支持的拼写填,改完立刻用一条中文数据验证,不要等到上线。

选utf8还是utf8mb4,取决于表里有没有 emoji 或者生僻字。MySQL 5.7 的utf8实际是三个字节的版本,四字节字符存不进去。有这类数据就必须上utf8mb4,同时服务端和表也要一起改,光改客户端参数没用。

BlobSize写-1是省心的做法。写死一个数值(比如 4096),超过的字段会被静默截断,取出来是半截数据,这种 bug 最难查,因为不报任何错。

超时类参数要有心理准备:不是每个驱动版本都支持,写了不生效也不会提示。真正的兜底还是在业务层加超时控制,别指望驱动参数。

5. 避坑清单:六条反复出现的报错和它们的成因

下面这六条是我在不同机器上真的踩过的,按现象、原因、解决三段写,遇到同款直接对照。

5.1 启动就报 error code 126

现象:程序一启动,或者第一次Connected := True时,弹Unable to load dbxopenmysql50.dll (error code 126)。

原因:三种可能——文件没在搜索路径里、文件位数不对、文件自身缺依赖。第三种最容易被忽略。

解决:先用dumpbin /dependents分别看两个 dll 的依赖列表,缺MSVCR120.dll就装运行库;依赖齐了就确认 exe 同目录下确实有这两个文件、位数和进程一致。挂 Process Monitor 看NAME NOT FOUND的路径,能直接定位它找的是哪。

5.2 报 error code 193

现象:报错信息里带error code 193,或者直接提示「不是有效的 Win32 应用程序」。

原因:位数不匹配。32 位进程加载了 64 位的 dll,或者反过来。这个错比 126 更明确,说明文件找到了,就是版本不对。

解决:按第 2.1 节确认宿主进程位数,把两个 dll 一起换成对应位数。注意两个要同时换,只换一个的话,报错会从 193 变成别的,容易误以为没修好。

5.3 连接成功,中文全是问号

现象:Connected正常,查询也返回数据,就是中文显示成???,英文和数字都正常。

原因:客户端字符集没生效。要么参数名拼错(Chartset写成了Charset),要么填的值和服务端、表的字符集对不上。

解决:先确认参数名拼写和驱动要求一致,再执行SHOW VARIABLES LIKE 'character_set_%'看服务端各层字符集。表是utf8mb4而客户端给utf8的情况很常见,四字节字符照样丢。改完用一条确定含中文的记录验证,别看英文数据。

5.4 拿 8.0 的客户端库配 5.7 的服务端

现象:连上去立刻断开,错误信息含糊,说认证失败但密码明明是对的。

原因:MySQL 8.0 默认的账号认证方式和 5.7 不一样,5.7 那一代的 libmysql.dll 不认识新的握手流程。

解决:保持客户端库和服务端大版本一致,5.7 的服务端就用 5.7 的 libmysql.dll。服务端已经升到 8.0 的,把业务账号的认证方式改成 5.7 认识的那一种,别去动驱动。

5.5 设计期能连,编译出来连不上

现象:在 IDE 里点测试连接一切正常,编译出的 exe 跑起来就报加载失败。

原因:设计期用的是 Delphi 安装目录下那份dbxdrivers.ini和那套 dll,编译出的程序读的是 exe 同目录的配置。两边环境不一样。

解决:把dbxdrivers.ini、dbxconnections.ini和两个 dll 都复制到输出目录,或者干脆全部改成运行时赋值,不依赖 ini。我现在新写的代码一律运行时给参数,就是为了避开这个差异。

5.6 本机正常,拷到客户机就崩

现象:开发机上跑了一周没问题,打包发到客户机,一启动就报 126。

原因:客户机缺 VC++ 运行库,或者装过别的软件,系统目录里有一份版本不对的 libmysql.dll 被优先加载了。

解决:安装包里带上运行库,两个 dll 固定放 exe 同目录,别依赖系统目录。交付前在干净的机器上跑一遍第 6 章的三步验证,不要拿开发机当验收环境。

6. 装完怎么验证:三步确认连接真的跑通

文件放好、参数填完,很多人到这一步就收工了,结果交付之后才发现是「能连上但用不了」。我现在的习惯是走完三步再算装完。

第一步,先撇开 Delphi,用命令行确认账号和服务端没问题。

mysql -h 127.0.0.1 -P 3306 -u erp -p -e "select version(), @@character_set_server, @@default_authentication_plugin;"

这条命令一次看三件事:服务端版本是不是 5.7、服务端默认字符集是什么、默认认证方式是哪一种。如果这一步就失败,那问题在账号权限或者网络,跟两个 dll 一点关系没有,别在客户端上浪费时间。

第二步,写一个最小的 Delphi 程序,只放一个TSQLConnection和一个TSQLQuery。

Query.SQL.Text := 'select version() as v, @@character_set_connection as cs'; Query.Open; Memo1.Lines.Add(Query.FieldByName('v').AsString); // 期望看到 5.7.x Memo1.Lines.Add(Query.FieldByName('cs').AsString); // 期望和客户端字符集一致 Query.Close;

这一步能过,说明驱动加载、客户端库加载、协议握手、字符集协商四关全通了。character_set_connection的值和你填的字符集参数对不上,就是第 4.3 节那个拼写问题。

第三步,用真实数据类型走一遍,别只查select 1。

验证项做法通过标准
中文插入一条含中文的记录再读回读回内容与写入一致
大字段写入超过 64KB 的文本或二进制读回长度一致,无截断
事务StartTransaction后插入再Rollback表里没有新增记录
重连断开后重新Connected := True能正常重连,不报错

大字段那一项专门用来验证BlobSize=-1有没有生效。事务那一项验证的是驱动对事务的支持程度,某些版本在自动提交上的行为和预期不一样,回滚不掉就很麻烦。

这三步加起来不到二十分钟,但能把后面交付阶段八成的返工挡掉。从那以后我每次换机器部署这套环境,都强制先走一遍这三步,再谈业务功能——「程序能打开」和「数据库真的通了」是两回事,中间隔着的正是那两个 dll 和一堆参数。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 17:04:53

Linux特殊符号:系统命令的隐藏语言与实战技巧

1. Linux特殊符号:被忽视的系统语言 在终端里敲下第一个 ls -l 命令时,大多数人都不会注意到那些看似装饰性的符号。直到某天我调试一个Shell脚本,发现 2>&1 这样的组合能让错误输出神奇地重定向——那一刻我才意识到,…

作者头像 李华
网站建设 2026/10/27 17:04:49

Python量化交易策略与回测系统源码解析:从策略逻辑到实盘衔接

简介:这是一套面向计算机相关专业学生与量化交易初学者的Python量化交易策略及回测系统完整项目,源自经导师指导并通过评审的毕业设计,评审分98分,难度适中,适合用作毕业设计参考或项目实战练习。资源包共15个文件&…

作者头像 李华
网站建设 2026/10/27 17:03:45

Machine Configurator:工业设备可验证配置治理方案

简介:Machine Configurator 是一款专为西门子UG-NX平台开发的机床验证辅助工具,面向数控仿真工程师、CNC系统集成人员及高端制造领域技术人员,用于构建和调试机床运动学模型、CSE驱动程序与后处理器,解决实际加工前G代码行为验证难…

作者头像 李华
网站建设 2026/10/27 17:03:44

Cocos Creator节点树与组件化开发实战指南

1. 项目概述"Day 02 搞懂节点树就搞懂了 Cocos —— 场景系统与组件化思想深度解析"这个标题直指Cocos引擎开发的核心概念。作为一名使用Cocos Creator开发过多款游戏的开发者,我深知节点树和组件化思想是掌握这个引擎的关键所在。在Cocos Creator中&…

作者头像 李华
网站建设 2026/10/27 17:03:43

桌面Agent语音本地跑:唤醒、识别、合成与打断的工程实战

坐在电脑前调了大半天桌面 Agent,我最大的感触是:真正让项目卡壳的,往往不是那个最炫酷的大模型,而是最不起眼的语音链路。你产品演示时,线上大模型反应飞快,识别率也漂亮,但一旦换到本地环境、…

作者头像 李华
网站建设 2026/10/27 17:03:16

物联网平台海量连接测试实战与性能优化

1. 物联网平台测试的核心挑战当我们需要测试一个支持海量设备连接的物联网平台时,首先得理解这种测试与传统软件测试的本质区别。想象一下,你管理的不是几十上百台设备,而是数以万计甚至百万计的终端同时在线、交互的场景。这种规模带来的复杂…

作者头像 李华