首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL C API 呼叫實戰:Windows DLL 與 Linux .so 編譯全流程

     編輯:MySQL 資料庫相關知識

背景

需開發 Erlang NIF 動態庫 mysql_nif.dll/.so,直接鏈結 MySQL C Client Library,記錄跨平台編譯關鍵點。

Windows (Visual Studio 2010)

庫檔說明

  • libmysql.dll:動態連結庫,執行期必須同目錄或 PATH 可見。
  • libmysql.lib:libmysql.dll 的匯入庫,靜態鏈結時用。
  • mysqlclient.lib:靜態庫,鏈結時不依賴 DLL,但需解決 CRT 衝突。

方案 A:動態鏈結 libmysql.lib(推薦)

  1. 專案屬性 → Linker → Input → Additional Dependencies 加入 libmysql.lib。
  2. 編譯產出 mysql_nif.dll。
  3. 部署時必須將 libmysql.dll 放在同目錄或系統 PATH。

方案 B:靜態鏈結 mysqlclient.lib

  1. 專案屬性 → Linker → Command Line 加入:
/nodefaultlib:LIBCMT.lib /nodefaultlib:MSVCRTD.lib

解決多重 CRT 衝突(MT vs MD),再加入 mysqlclient.lib 鏈結。

Linux (GCC)

gcc -fPIC -shared -o mysql_nif.so mysql_nif.c \
  -I /usr/local/mysql/include/mysql \
  -L /usr/local/mysql/lib/mysql \
  -l mysqlclient \
  -I /usr/local/lib/erlang/erts-5.8/include
  • -fPIC -shared:產生位置無關程式碼共享庫。
  • -l mysqlclient:鏈結 libmysqlclient.so(通常在 /usr/lib/mysql 或 MySQL 安裝目錄)。
  • 若找不到庫,執行 ldconfig 或設定 LD_LIBRARY_PATH。

核心 API 呼叫流程

MYSQL *conn = mysql_init(NULL);
if (!mysql_real_connect(conn, "host", "user", "pass", "db", 3306, NULL, 0)) {
    fprintf(stderr, "Connect failed: %s\n", mysql_error(conn));
    return;
}
if (mysql_query(conn, "SELECT VERSION()")) {
    fprintf(stderr, "Query failed: %s\n", mysql_error(conn));
}
MYSQL_RES *res = mysql_store_result(conn);
while (MYSQL_ROW row = mysql_fetch_row(res)) {
    printf("Version: %s\n", row[0]);
}
mysql_free_result(res);
mysql_close(conn);

常見坑點

  1. 標頭檔路徑:Windows 需指向 include 目錄,Linux 通常 /usr/include/mysql。
  2. my_bool 型別在 MySQL 8.0 棄用,改用 bool 或 unsigned char。
  3. 字符集:連線後立即 mysql_set_character_set(conn, "utf8mb4")。
  4. 執行緒安全:多執行緒環境每執行緒獨立 MYSQL 物件,或使用 mysql_thread_init()。

總結

Windows 推薦動態鏈結 libmysql.lib + 部署 DLL,避免 CRT 地雷;Linux 直接 -lmysqlclient 最省心。核心流程 init → connect → query → fetch → free → close 不變,注意資源釋放與錯誤處理即可穩定整合。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved