3.2 构建 C API 客户端程序

本节提供编译使用 MySQL C API 的 C 程序的指南。

在 Unix 上编译 MySQL 客户端

这里的示例使用 gcc 作为编译器。在某些系统上,其他编译器可能更合适(例如,macOS 或 FreeBSD 上的 clang,或 Solaris 上的 Sun Studio)。请根据需要调整示例。

编译使用 MySQL 头文件的客户端程序时,您可能需要指定 -I 选项,以便编译器可以找到它们。例如,如果头文件安装在 /usr/local/mysql/include 中,请在编译命令中使用以下选项

-I/usr/local/mysql/include

您可以将代码与动态或静态 MySQL C 客户端库链接。动态库的基本名称是 libmysqlclient,后缀因平台而异(例如,Linux 为 .so,macOS 为 .dylib)。静态库在所有平台上都命名为 libmysqlclient.a

必须使用链接命令中的 -lmysqlclient 选项链接 MySQL 客户端。您可能还需要指定 -L 选项来告诉链接器在哪里可以找到该库。例如,如果库安装在 /usr/local/mysql/lib 中,请在链接命令中使用以下选项

-L/usr/local/mysql/lib -lmysqlclient

路径名在您的系统上可能会有所不同。请根据需要调整 -I-L 选项。

为了更轻松地在 Unix 上编译 MySQL 程序,请使用 mysql_config 脚本。请参阅 mysql_config — 显示用于编译客户端的选项

mysql_config 显示编译或链接所需的选项

mysql_config --cflags
mysql_config --libs

您可以在命令行调用这些命令以获取正确的选项,并将它们手动添加到编译或链接命令中。或者,使用反引号将 mysql_config 的输出直接包含在命令行中

gcc -c `mysql_config --cflags` progname.c
gcc -o progname progname.o `mysql_config --libs`

在 Unix 上,默认情况下链接使用动态库。要改为链接到静态客户端库,请将其路径名添加到链接命令中。例如,如果库位于 /usr/local/mysql/lib 中,请像这样链接

gcc -o progname progname.o /usr/local/mysql/lib/libmysqlclient.a

或者使用 mysql_config 提供库的路径

gcc -o progname progname.o `mysql_config --variable=pkglibdir`/libmysqlclient.a

mysql_config 目前没有提供列出静态链接所需的所有库的方法,因此可能需要在链接命令中命名其他库(例如,Solaris 上的 -lnsl -lsocket)。要了解要添加哪些库,请使用 mysql_config --libsldd libmysqlclient.so(或 macOS 上的 otool -L libmysqlclient.dylib)。

pkg-config 可以用作 mysql_config 的替代方法,用于获取编译 MySQL 应用程序所需的编译器标志或链接库等信息。例如,以下命令对是等效的

mysql_config --cflags
pkg-config --cflags mysqlclient

mysql_config --libs
pkg-config --libs mysqlclient

要生成用于静态链接的标志,请使用以下命令

pkg-config --static --libs mysqlclient

有关更多信息,请参阅 第 3.3 节,“使用 pkg-config 构建 C API 客户端程序”

在 Microsoft Windows 上编译 MySQL 客户端

要指定头文件和库文件的位置,请使用您的开发环境提供的功能。

要在 Windows 上构建 C API 客户端,您必须链接 C 客户端库,以及 Windows ws2_32 套接字库和 Secur32 安全库。

您可以将代码与动态或静态 MySQL C 客户端库链接

  • 动态库名为 libmysql.dll。此外,使用动态库需要 libmysql.lib 静态导入库。

  • 静态库名为 mysqlclient.lib。要链接静态 C 客户端库,客户端应用程序必须使用与编译 C 客户端库相同的 Visual Studio 版本进行编译(Oracle 构建的静态 C 客户端库使用的是 Visual Studio 2015)。

使用 Oracle 构建的 MySQL C 客户端库时,在链接客户端应用程序的 C 运行时时,请遵循以下规则

  • 对于来自 MySQL 社区发行的 MySQL C 客户端库

  • 对于来自 MySQL 商业发行的 MySQL C 客户端库

    • 如果链接到静态 C 客户端库,请静态链接到 C 运行时(使用 /MT 编译器选项)。

    • 如果链接到动态 C 客户端库,请静态或动态链接到 C 运行时(使用 /MT/MD 编译器选项)。

通常,当链接到静态 MySQL C 客户端库时,客户端库和客户端应用程序在链接 C 运行时时必须使用相同的编译器选项,也就是说,如果您的 C 客户端库是使用 /MT 选项编译的,那么您的客户端应用程序也应该使用 /MT 选项编译,依此类推(有关更多详细信息,请参阅 描述 C 库链接选项的 MSDN 页面)。当您从 MySQL 源代码发行版构建自己的静态 MySQL C 客户端库并将其链接到您的客户端应用程序时,请遵循此规则。

注意

调试模式: 由于刚才提到的链接规则,您无法在调试模式下构建应用程序(使用 /MTd/MDd 编译器选项)并将其链接到 Oracle 构建的静态 C 客户端库,该库没有使用调试选项构建。相反,您必须使用调试选项从源代码构建静态客户端库。

链接到 MySQL 客户端库时解决问题

MySQL 客户端库内置了 SSL 支持。在链接时不需要指定 -lssl-lcrypto。这样做实际上可能会在运行时导致问题。

如果链接器无法找到 MySQL 客户端库,您可能会收到以 mysql_ 开头的符号的未定义引用错误,如下所示

/tmp/ccFKsdPa.o: In function `main':
/tmp/ccFKsdPa.o(.text+0xb): undefined reference to `mysql_init'
/tmp/ccFKsdPa.o(.text+0x31): undefined reference to `mysql_real_connect'
/tmp/ccFKsdPa.o(.text+0x69): undefined reference to `mysql_error'
/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to `mysql_close'

您应该能够通过在链接命令的末尾添加 -Ldir_path -lmysqlclient 来解决此问题,其中 dir_path 表示客户端库所在的目录的路径名。要确定正确的目录,请尝试以下命令

mysql_config --libs

mysql_config 的输出可能还会指示应该在链接命令中指定的其他库。您可以使用反引号将 mysql_config 输出直接包含在您的编译或链接命令中。例如

gcc -o progname progname.o `mysql_config --libs`

如果在链接时发生错误,指出 floor 符号未定义,请通过在编译/链接行的末尾添加 -lm 来链接到数学库。类似地,如果您收到系统上应该存在的其他函数(例如 connect())的未定义引用错误,请查看相关函数的手册页,以确定应该将哪些库添加到链接命令中。

如果您的系统上不存在的函数(例如以下函数)出现未定义引用错误,则通常意味着您的 MySQL 客户端库是在与您的系统不完全兼容的系统上编译的

mf_format.o(.text+0x201): undefined reference to `__lxstat'

在这种情况下,您应该下载最新版 MySQL 的源代码发行版,并自己编译 MySQL 客户端库。请参阅 从源代码安装 MySQL