gpt4 book ai didi

mysql - 在 C 中的函数中将 MySQL 连接保持在静态变量中(避免使用全局变量)

转载 作者:行者123 更新时间:2023-11-29 01:40:17 24 4
gpt4 key购买 nike

我正在用 C 创建一个 MySQL 层(在 GWAN 中运行)并试图避免将 MySQL 连接保存在一个全局变量中。

我的简化代码如下所示:

    #include <mysql.h>

const char *DB_HOST = "localhost";
const char *DB_USER = "user";
const char *DB_PASSWORD = "pass";
const char *DB_DATABASE = "xxx";
const unsigned int DB_PORT = 3306;
const char *DB_CHARACTER_SET = "utf8";
const char *DB_SOCKET = 0;
const unsigned long DB_CLIENT_FLAG=0;

typedef struct DB_Data {
//database returned data
} DB_Data;

//connect to database and return the connection
MYSQL *db_connect() {

static MYSQL *db_connection = NULL;

if(db_connection == NULL) {

printf(" NEW CONN \n");

db_connection = (MYSQL *)mysql_init(NULL);

if(!db_connection) {
return NULL;
}

//connect to the database using settings
if(mysql_real_connect(db_connection, DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE, DB_PORT, DB_SOCKET, DB_CLIENT_FLAG) == NULL) {
return NULL;
}

//set character set
if (mysql_set_character_set(db_connection, DB_CHARACTER_SET)) {
return NULL;
}

}else{
printf(" OLD CONN \n");
}

return db_connection;
}

//close the database connection
void db_close() {

//get connection
MYSQL *db_connection = db_connect();

if(db_connection != NULL) {

printf("\n closing... \n");

//close connection
mysql_close(db_connection);

//set pointer to null
//Fail: this does not effect the static variable in db_connect()
db_connection = NULL;
}
}

//query the database
DB_Data *db_query(char *sql, bool getResult) {

DB_Data *rtn;
MYSQL_ROW row = NULL;

//create connection if not already done
MYSQL *db_connection = db_connect();
//db_connect();
if(db_connection == NULL) {
return NULL;
}

if(mysql_query(db_connection, sql) != 0) {
return NULL;
}

if(getResult != true) {
return NULL;
}

MYSQL_RES *result = mysql_store_result(db_connection);

if(result == NULL) {
return NULL;
}

while ((row = mysql_fetch_row(result))) {
//process data
printf("Process data \n");
}

mysql_free_result(result);

return rtn;
}

一切正常,直到我开始使用 db_close() 关闭连接。在我的代码中似乎失败的是在 db_close() 中 db_connection 没有设置为 NULL。在运行 db_close() 然后再次运行 db_connect() 之后,db_connection 的值不是 NULL,而是与第一次运行 db_connect() 时获得的值相同。

用mysql_close(db_connection)关闭连接或者执行查询都没有问题,所以db_connection(db_connect()返回)是有效的。

如果我将 db_connection 作为全局变量,那么 db_close() 也可以工作,但我试图避免使用全局变量。

以上代码为简化版。我已经尝试了一些事情,比如将 MYSQL ** 作为 db_connection 传递,但我还没有让它工作。

信息和/或一些示例代码会很棒!

最佳答案

首先 - 一个简单但有点“歪曲”的解决方案可能是只使用一个名为“db_action”的函数,该函数接收一个作为一种标志的整数变量:当标志为“0”时,您尝试连接到数据库,当标志为“1”时,您将断开连接:

    MYSQL *db_action(int flag) {

static MYSQL *db_connection = NULL;

if(flag == 0 && db_connection == NULL) {

printf(" NEW CONN \n");

db_connection = (MYSQL *)mysql_init(NULL);

...
}
else if(flag == 1 && db_connection != NULL){
printf("\n closing... \n");

//close connection
mysql_close(db_connection);

//set pointer to null
db_connection = NULL;
}
else{
printf(" OLD CONN \n");
}

return db_connection;
}

如果你真的想使用一个全局变量来做空的话。在我看来,你的连接变量应该是全局的是有道理的,因为它可能会在程序的整个运行时使用,并被不同的函数使用。在 c/php/ruby 等许多基本的 mysql 教程中,他们通常使用全局变量。

我想让您了解为什么不能在 db_close 函数中将 db_connection 变量设置为 NULL。

当您首先在 db_connect 函数中声明 static MYSQL *db_connection = NULL; 时,您正在创建一个新的静态变量(这意味着它只初始化一次)并将其设置为 NULL。您可以在此处阅读更多信息:wikipedia static_variable

然后退出(您的代码退出...)db_connect 函数。现在 db_connection 变量超出范围 - 你不能“使用”它(读取它的数据或改变它)。您只能在 db_connect 函数中执行此操作。

在 db_close 中,您获得了先前的数据库连接,MYSQL *db_connection = db_connect(); 但是请注意,因为您将 *db_connection 声明为 MYSQL 类型的新变量(它是指向 MYSQL 变量的指针) 它现在在 db_close 函数的范围内 - 它不能影响你之前创建的静态变量 - 它们是两个完全不同的变量 - 它们只在你调用 db_connect() 时共享相同的数据。

范围和/或堆/堆栈机制是您在开发任何类型的软件时都必须了解的内容。当您作为程序员有更多责任管理程序中不同变量的内存分配时,尤其是 C/C++ 或类似语言。在这里阅读更多相关信息:Memory allocation, Heap and Stack

汤姆。

关于mysql - 在 C 中的函数中将 MySQL 连接保持在静态变量中(避免使用全局变量),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26285188/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com