You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中传递MySQL连接句柄并维持有效连接?

修复MySQL连接句柄传递失效问题

问题原因

你遇到的核心问题是函数参数传递方式错误:

  • ConnectToSQL函数接收的MYSQL *conn是值传递,函数内对conn的赋值(conn = mysql_init(NULL)、conn = mysql_real_connect(...))仅修改了函数内部的局部指针副本,外部主函数中的conn变量完全没收到这个新的连接指针。
  • 主函数中定义的MYSQL conn;是栈上的结构体实例,但MySQL API的连接句柄需要通过mysql_init动态分配,直接用栈实例会导致后续操作出错。

解决方案

  1. 将ConnectToSQL的连接句柄参数改为指针的指针(MYSQL **conn),让函数能直接修改外部的指针变量。
  2. 主函数中直接定义MYSQL *conn指针(而非栈结构体),初始化为NULL,调用ConnectToSQL时传入它的地址。
  3. 修复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 09:11:54