Windows 下可通過 ODBC 驅動訪問,Linux 同樣支持 ODBC,但原生 C API (libmysqlclient) 性能更優、依賴更少。本節系統講解核心 API 調用流程。
兩步建立連接:
步驟 1:mysql_init 初始化句柄
#include <mysql.h>
MYSQL *mysql_init(MYSQL *mysql);
NULL → 分配並返回新結構指針NULL步驟 2:mysql_real_connect 建立連接
MYSQL *mysql_real_connect(MYSQL *connection,
const char *host, // 主機名或 IP,localhost 走 Unix socket 優化
const char *user, // 用戶名,NULL 取當前系統用戶
const char *password, // 密碼,NULL 僅訪問無密庫
const char *database, // 默認庫
unsigned int port, // 0 使用默認 3306
const char *unix_socket, // NULL 使用默認 socket
unsigned int flags); // 特殊協議標誌 (壓縮、SSL 等)
connection 必須是 mysql_init 初始化過的指針NULL,調用 mysql_error() 獲取詳情連接選項設置 (mysql_options)
int mysql_options(MYSQL *connection, enum option, const char *arg);
常用選項:
| 選項 | 參數類型 | 說明 |
|---|---|---|
| MYSQL_OPT_CONNECT_TIMEOUT | const unsigned int* | 連接超時秒數 |
| MYSQL_OPT_COMPRESS | NULL | 啟用壓縮協議 |
| MYSQL_INIT_COMMAND | const char* | 連接建立後自動執行的 SQL |
// 設置 7 秒連接超時
unsigned int timeout = 7;
conn = mysql_init(NULL);
mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, (char*)&timeout);
conn = mysql_real_connect(conn, "localhost", "rick", "secret", "foo", 0, NULL, 0);
關閉連接
void mysql_close(MYSQL *connection);
mysql_init 分配的內存#include <stdio.h>
#include <mysql.h>
int main() {
MYSQL *conn = mysql_init(NULL);
if (!conn) { fprintf(stderr, "mysql_init failed\n"); return 1; }
if (!mysql_real_connect(conn, "localhost", "rick", "secret", "foo", 0, NULL, 0)) {
fprintf(stderr, "Connect failed: %s\n", mysql_error(conn));
mysql_close(conn);
return 1;
}
printf("Connected to MySQL successfully!\n");
mysql_close(conn);
return 0;
}
編譯命令 (若報 mysql.h 缺失,參見 Linux 找不到 mysql.h 解決方案):
gcc connect1.c -o connect1 -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient
MySQL C API 通過連接句柄返回錯誤信息,兩大核心函數:
unsigned int mysql_errno(MYSQL *conn); // 錯誤碼,0 表示無錯誤
char *mysql_error(MYSQL *conn); // 人類可讀錯誤文本
關鍵點:
errmsg.h (客戶端) 和 mysqld_error.h (服務端)mysql_error 返回靜態緩衝區指針,若需持久化請 strdup 複製mysql_real_connect 失敗返回 NULL,但若句柄為堆疊變量而非動態分配,仍可通過該句柄調用錯誤函數MYSQL conn; // 非動態分配
mysql_init(&conn);
if (!mysql_real_connect(&conn, "localhost", "rick", "secret", "foo", 0, NULL, 0)) {
fprintf(stderr, "Connect error %u: %s\n", mysql_errno(&conn), mysql_error(&conn));
return 1;
}
// ... 業務邏輯
mysql_close(&conn);
goto cleanup 或 RAII 包裝器確保異常路徑釋放連接mysql_stmt_prepare 系列 API 防注入、提升重複執行性能SET NAMES utf8mb4 避免亂碼