MySQL - 如何在 C 使用

要先安裝好 MySQL ,取得 libmysqlclient.so 之後
用 dlopen 將會用到的 func 都找出來
之後就可以直接使用了~

或在編譯時加 -lmysqlclient 直接使用 func


放在 lib.so 裡


#include<dlfcn.h>
#define MYSQL_SHARE_LIB_PATH "/usr/lib/libmysqlclient.so"

static int func_open_f = 0;

static void *handle = NULL;
static int( * _mysql_connect)(MYSQL * mysql,char *charset);
static int( * _mysql_query)(MYSQL * mysql,char *format, ...);
static void( * _mysql_close)(MYSQL * sock);
static my_bool( * _mysql_reconnect)(MYSQL * mysql);

MYSQL_RES * (STDCALL * my_mysql_store_result) (MYSQL * mysql);
my_ulonglong(STDCALL * my_mysql_num_rows) (MYSQL_RES * res);
my_ulonglong(STDCALL * my_mysql_affected_rows) (MYSQL * mysql);
MYSQL_ROW(STDCALL * my_mysql_fetch_row) (MYSQL_RES * result);
void(STDCALL * my_mysql_free_result) (MYSQL_RES * result);
void(STDCALL * my_mysql_data_seek) (MYSQL_RES * result, my_ulonglong offset);
unsigned int(STDCALL * my_mysql_errno) (MYSQL * mysql);
const char *(STDCALL * my_mysql_error) (MYSQL * mysql);
int(STDCALL * my_mysql_ping) (MYSQL * mysql);
MYSQL_RES * (STDCALL * my_mysql_use_result) (MYSQL * mysql);
unsigned int(STDCALL * my_mysql_num_fields) (MYSQL_RES * result);
MYSQL_FIELD * (STDCALL * my_mysql_fetch_fields) (MYSQL_RES * result);

static void function_close (void) {
if (handle) {
dlclose(handle);
handle = NULL;
}
func_open_f = 0;
}

static void function_open (void) {
if (handle != NULL)
function_close();

if ((handle = dlopen(MYSQL_SHARE_LIB_PATH, RTLD_LAZY))) {
if (!(_mysql_connect = dlsym(handle, "MySQL_CONNECT")))
goto err_close;

if (!(_mysql_reconnect = dlsym(handle, "mysql_reconnect")))
goto err_close;

if (!(_mysql_query = dlsym(handle, "MySQL_QUERY")))
goto err_close;

if (!(my_mysql_store_result = dlsym(handle, "mysql_store_result")))
goto err_close;

if (!(my_mysql_num_rows = dlsym(handle, "mysql_num_rows")))
goto err_close;

if (!(my_mysql_fetch_row = dlsym(handle, "mysql_fetch_row")))
goto err_close;

if (!(my_mysql_affected_rows = dlsym(handle, "mysql_affected_rows")))
goto err_close;

if (!(my_mysql_free_result = dlsym(handle, "mysql_free_result")))
goto err_close;

if (!(_mysql_close = dlsym(handle, "mysql_close")))
goto err_close;

if (!(my_mysql_data_seek = dlsym(handle, "mysql_data_seek")))
goto err_close;

if (!(my_mysql_errno = dlsym(handle, "mysql_errno")))
goto err_close;

if (!(my_mysql_error = dlsym(handle, "mysql_error")))
goto err_close;

if (!(my_mysql_ping = dlsym(handle, "mysql_ping")))
goto err_close;

if (!(my_mysql_use_result = dlsym(handle, "mysql_use_result")))
goto err_close;

if (!(my_mysql_num_fields = dlsym(handle, "mysql_num_fields")))
goto err_close;

if (!(my_mysql_fetch_fields = dlsym(handle, "mysql_fetch_fields")))
goto err_close;

func_open_f = 1;
return;
}
err_close:
function_close();
}

int my_mysql_connect (MYSQL * mysql,char *charset) {
#define RETRY_TIMES 10
int times = RETRY_TIMES, result = -1;

if (!func_open_f)
function_open();

if (!func_open_f)
return result;

/* connect mysql */
while (times-- > 0) {
if ((result = _mysql_connect(mysql, charset)) >= 0)
break;

sleep(1);
}

return result;
}

int my_mysql_query (MYSQL * mysql,char *format, ...) {
va_list arg;
int times = 5, result = -1;
char *query = NULL;


if (!func_open_f)
function_open();

if (!func_open_f)
return result;

va_start(arg, format);
vasprintf( & query, format, arg);
va_end(arg);

if (query) {
while (times-- > 0) {
if ((result = _mysql_query(mysql, "%s", query)) >= 0)
break;

/* Duplicate entry */
if (my_mysql_errno(mysql) == 1062)
break;

while (_mysql_reconnect(mysql)) sleep(1);

sleep(2);
}

if (times <= 0)
syslog(LOG_ERR, "Can't run this query: %s", query);

free(query);
}

return result;
}

void my_mysql_close(MYSQL * mysql) {
_mysql_close(mysql);
}



使用方法


MYSQL mysql;
MYSQL_RES *res = NULL;
MYSQL_ROW row;
if (my_mysql_connect(&mysql, NULL) < 0)
return;
if(my_mysql_query(&mysql, "SELECT * FROM `%s`.`%s`", "db_name", "tb_name") != 0)
return;
if ((res = my_mysql_store_result(&mysql))) {
while ((row = my_mysql_fetch_row(res))) {
printf("%s, %s", row[0], row[1]);
}
my_mysql_free_result(res);
}
my_mysql_close(&mysql);






沒有留言:

張貼留言