前置需求
- Visual C++ 6.0 / VS 2005+
- MySQL 原始碼套件(含
include、lib 目錄)
- 已啟動的 MySQL 服務
步驟總覽
- 開啟
mysqld.dsw 工作區 → 新增專案「Win32 Dynamic-Link Library」,名稱 my_udf。
- 選「An Empty DLL Project」完成建立。
- 新增
my_udf.cpp:
#include
#include
#include
extern "C" {
char *my_name(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error);
}
char *my_name(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error)
{
char *me = "my name"; // 靜態字串,生命週期需持久
return me;
}
- 新增
my_udf.def 匯出定義:
LIBRARY UDF_EXAMPLE
DESCRIPTION 'Example Using UDF with VC++'
VERSION 1.0
EXPORTS
my_name
- 專案屬性 → C/C++ → General → Additional Include Directories 加入 MySQL
include 路徑(如 ..\include)。
- Preprocessor Definitions 加入
HAVE_DLOPEN。
- F7 編譯產出
my_udf.dll。
- 複製 DLL 到系統路徑(
C:\Windows\System32 或 MySQL\bin)。
- MySQL 註冊函數:
CREATE FUNCTION my_name RETURNS STRING SONAME 'my_udf.dll';
常見坑與解法
| 現象 | 原因 | 對策 |
編譯卡在 sql_yacc.cc 久久不動 |
GCC 對內聯函數優化需大量記憶體 |
加 --with-low-memory 或手動在 Makefile 加 -fno-inline/-O0 |
啟動報錯 Can't open shared library |
DLL 不在 PATH 或相依 libmysql.dll 缺失 |
放入 System32 或 MySQL\bin;依賴走向檢查 |
| 函數回傳亂碼/ Crash |
回傳指標指向區域變數 |
使用靜態緩衝區、或 initid->ptr = malloc(...) 在 xxx_init 配置,xxx_deinit 釋放 |
無法載入 my_udf.dll (Error 126) |
缺少 VC++ Runtime (MSVCRT) |
安裝對應 Visual C++ Redistributable |
進階:帶初始化/反初始化的完整範例
my_bool my_sum_init(UDF_INIT *initid, UDF_ARGS *args, char *msg) {
if (args->arg_count != 1 || args->arg_type[0] != INT_RESULT) {
strcpy(msg, "my_sum() requires one integer argument");
return 1;
}
initid->maybe_null = 0;
initid->max_length = 20;
return 0;
}
void my_sum_deinit(UDF_INIT *initid) { /* nothing */ }
long long my_sum(UDF_INIT *initid, UDF_ARGS *args,
char *is_null, char *error) {
long long sum = 0;
for (uint i = 0; i < args->args[0]; ++i) sum += i;
return sum;
}