如何在C语言中传递MySQL连接句柄并维持有效连接?
修复MySQL连接句柄传递失效问题
问题原因
你遇到的核心问题是函数参数传递方式错误:
ConnectToSQL函数接收的MYSQL *conn是值传递,函数内对conn的赋值(conn = mysql_init(NULL)、conn = mysql_real_connect(...))仅修改了函数内部的局部指针副本,外部主函数中的conn变量完全没收到这个新的连接指针。- 主函数中定义的
MYSQL conn;是栈上的结构体实例,但MySQL API的连接句柄需要通过mysql_init动态分配,直接用栈实例会导致后续操作出错。
解决方案
- 将
ConnectToSQL的连接句柄参数改为指针的指针(MYSQL **conn),让函数能直接修改外部的指针变量。 - 主函数中直接定义
MYSQL *conn指针(而非栈结构体),初始化为NULL,调用ConnectToSQL时传入它的地址。 - 修复
QuerySQL函数中的逻辑错误(比如未初始化resultado就判断、错误的mysql_query返回值判断)。
修正后的完整代码
#include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <stdio.h> #include <ctype.h> #include <stdbool.h> #include <mysql.h> // 函数声明 void ConnectToSQL(char respuesta_sql[300], MYSQL **conn); void DisconnectFromSQL(char respuesta_sql[300], MYSQL *conn); int QuerySQL(char consulta[300], MYSQL *conn, MYSQL_ROW *row); // 创建MySQL连接 void ConnectToSQL(char respuesta_sql[300], MYSQL **conn) { char *server = "localhost"; char *user = "root"; char *password = "mysql"; char *database = "ProyectoSO"; // 初始化连接句柄,直接修改外部指针 *conn = mysql_init(NULL); if (*conn == NULL) { sprintf(respuesta_sql, "Error al crear la conexion: %u %s", mysql_errno(*conn), mysql_error(*conn)); return; } // 建立实际连接 *conn = mysql_real_connect(*conn, server, user, password, database, 0, NULL, 0); if (*conn == NULL) { sprintf(respuesta_sql, "Error al inicializar la conexion: %u %s", mysql_errno(*conn), mysql_error(*conn)); } else { sprintf(respuesta_sql, "Exito"); } } // 断开MySQL连接 void DisconnectFromSQL(char respuesta_sql[300], MYSQL *conn) { if (conn != NULL) { mysql_close(conn); sprintf(respuesta_sql, "Desconectado"); } else { sprintf(respuesta_sql, "No hay conexion activa"); } } // 执行SQL查询 int QuerySQL(char consulta[300], MYSQL *conn, MYSQL_ROW *row) { MYSQL_RES *resultado = NULL; int err; int resultado_consulta = -1; if (conn == NULL) { return resultado_consulta; // 无有效连接,直接返回错误 } err = mysql_query(conn, consulta); if (err != 0) { // mysql_query返回非0表示查询失败 resultado_consulta = -1; } else { // 存储查询结果 resultado = mysql_store_result(conn); if (resultado != NULL) { *row = mysql_fetch_row(resultado); // 注意:使用完resultado后需要mysql_free_result释放,避免内存泄漏 } resultado_consulta = 0; } return resultado_consulta; } int main(int argc, char *argv[]) { MYSQL *conn = NULL; // 直接定义连接指针,初始化为NULL char respuesta_sql[300]; ConnectToSQL(respuesta_sql, &conn); printf("%s\n", respuesta_sql); // 示例:执行查询 if (conn != NULL) { MYSQL_ROW row; if (QuerySQL("SELECT * FROM tu_tabla", conn, &row) == 0 && row != NULL) { printf("Resultado: %s\n", row[0]); // 打印第一列数据 } } DisconnectFromSQL(respuesta_sql, conn); printf("%s\n", respuesta_sql); return 0; }
额外注意事项
- 使用
mysql_store_result获取结果后,必须调用mysql_free_result(resultado)释放内存,避免内存泄漏(示例中未添加,需根据实际场景补充)。 - 始终检查连接句柄是否为
NULL后再执行操作,避免空指针访问崩溃。 mysql_query的返回值规则:0表示成功,非0表示失败,不需要判断err!=1,之前的逻辑有误。
内容的提问来源于stack exchange,提问作者Roberto Guarneros
相关产品推荐
相关产品推荐

