VS2019编写C++ MySQL UDF运行崩溃及返回值异常问题求助
问题排查与修复方案
第一个问题(long long类型UDF崩溃)原因
你在创建函数时指定的返回类型和代码实际返回类型不匹配:
- 代码中
test函数返回值为long long,对应MySQL UDF的返回类型应为INTEGER - 你执行的创建语句写了
returns string,MySQL按照字符串类型UDF的调用约定传递参数,导致栈结构异常,直接触发mysqld进程崩溃,因此出现连接中断报错。
修复方案:将创建语句修改为
CREATE FUNCTION test returns integer soname 'myUdf.dll';
第二个问题(string类型UDF返回值异常)原因
共存在3处核心错误:
- init函数返回值类型错误:MySQL官方UDF规范中,
xxx_init函数的返回值类型为int(0表示初始化成功,非0表示失败),你定义为bool类型,Windows x64环境下bool占1字节、int占4字节,调用约定不匹配导致后续参数传递全部错位,是返回值异常的核心原因。 sizeof(message)取值错误:message是指针类型,x64下sizeof(message)固定为8,而非message缓冲区的实际大小(MySQL规定该缓冲区大小为MYSQL_ERRMSG_SIZE,通常为512字节),直接传入会导致strcpy_s缓冲区长度判断错误,触发安全检查终止执行。- 未设置
is_null标识:返回有效字符串时需要将*is_null = 0,避免MySQL判定返回值为空。
修复后的string类型UDF代码示例
#include <string.h> #include "mysql.h" #if defined(_WIN32) || defined(_WIN64) #define DLLEXP __declspec(dllexport) #else #define DLLEXP #endif #ifdef __cplusplus extern "C" { #endif DLLEXP int test_init(UDF_INIT* initid, UDF_ARGS* args, char* message); DLLEXP char* test(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error); DLLEXP void test_deinit(UDF_INIT* initid); #ifdef __cplusplus } #endif int test_init(UDF_INIT* initid, UDF_ARGS* args, char* message) { if (args->arg_count != 0) { strcpy_s(message, MYSQL_ERRMSG_SIZE, "No arguments allowed"); return 1; } // 可选:设置最大返回长度,避免返回截断 initid->max_length = 5; return 0; } char* test(UDF_INIT* initid, UDF_ARGS* args, char* result, unsigned long* length, char* is_null, char* error) { strcpy_s(result, initid->max_length + 1, "hello"); *length = 5; *is_null = 0; *error = 0; return result; } void test_deinit(UDF_INIT* initid) {}
额外注意事项
- 编译dll时必须和MySQL的运行时库版本保持一致,避免CRT冲突
- 每次修改dll前需要先执行
DROP FUNCTION test;,替换dll后再重新创建函数,避免MySQL缓存旧的dll代码。
内容的提问来源于stack exchange,提问作者Chu Artistmonkey
相关产品推荐
相关产品推荐

