日期:2014-05-16  浏览次数:20409 次

c/c++连接mysql数据库

        由于项目需要,要用c/c++链接mysql数据库。网上很多类似的解说,但是大部分都需要在本机器上安装完整版的msyql。其实,有时候我们并不想在改变自己电脑上原有的环境,但是我们却希望通过我们的程序链接数据库。比如:我在本机上已经安装了一个mysql,但并不是完整版的(比如appserv集成mysql或者wamp集成mysql),或者我的工作在局域网中,我只需要链接另外一台机器上的mysql。这样,为链接mysql而从头安装mysql server并不是一个最佳的选择。

        mysql官网中提供了connector能够满足我们的需求。截止到目前,connector的种类有:ODBC、NET、J、Python、C++、C、PHP。由于C++包含了C,而对于我而言更习惯C的链接方式,所以,本人采用了Connector/C。官网的下载地址为:http://dev.mysql.com/downloads/connector/,但是下载需要注册,我早就忘了oracle的账号了,后来又重新注册了一下。为防止一些人遇到与我一样的问题,我上传了一些Connector for c/c++,以供大家下载使用。下载网址为:点击打开链接。

        将下载的mysql-connector-c-6.1.2-win32.zip解压,重命名目录名为mysql,并将mysql文件夹剪切至vs工作目录中。本人的vs版本为2008。然后改成release模式,添加mysql的include目录(项目工作目录/mysql/include)到工程(右击 - 属性- 配置属性 - C/C++ - 常规- 附加包含目录),添加mysql的lib目录(项目工作目录/mysql/lib)到工程(右击 - 属性- 配置属性 - 连接器- 常规-附加包含目录)。这种方式为动态链接,在编译后的exe文件运行时,需要把libmysql.dll文件拷贝到exe文件的同目录中,这用起来比较麻烦。如何把所有的代码都打包在一个exe中呢?我们还可以在链接的时候用mysqlclient.lib库。具体为:添加mysql的lib下对应的vc版本目录到工程而不是lib目录。比如:我用的是vs2008,其内部版本号为vs9,那么我将项目工作目录/mysql/lib/vs9目录添加到工程中(右击 - 属性- 配置属性 - 连接器- 常规-附加包含目录)。vs的版本号与年份的对应关系如下图所示。


          一个示例代码如下:

#include "mysql.h"
#include <stdio.h>

#pragma comment(lib, "mysqlclient.lib") 
#pragma comment(linker,"/nodefaultlib:LIBCMT.lib")  
#pragma comment(linker,"/nodefaultlib:MSVCRTD.lib")  
int main(int argc,char **argv)
{
	MYSQL* mysql = NULL;
	mysql = mysql_init(mysql);

	MYSQL_RES* res;
	MYSQL_ROW record;

	mysql_real_connect(mysql, "localhost", "root","123456", "kangry", 3306, NULL, NULL);
	mysql_query(mysql, "select * from whu_user;");
	res = mysql_store_result(mysql);
	while((record=mysql_fetch_row(res)))
	{
		printf("user_id=%s,user_name=%s,user_password=%s\n", record[0], record[1], record[2]);
	}
	mysql_free_result(res);
	mysql_close(mysql);
	
	getchar();

	return 0;	
}
其中代码第四行是链接lib文件,第5、6行必须加上,表示忽略LIBCMT.lib和MSVCRTD.lib库。否则会报类似如下错误:

error LNK2005: __configthreadlocale 已经在 MSVCRT.lib(MSVCR90.dll) 中定义


        若最开始未调成release模式,那么在添加mysql的lib时需要将工作目录/mysql/lib/vs9/debug目录添加到工程,并将项目的运行时库改成MT(多线程),具体为:项目邮件-》属性-》配置属性-》C/C++-》代码生成-》运行时库。否则,可能会报如下错误:warning LNK4217: 本地定义的符号 _printf 在函数 _main 中导入。

        希望我的随笔能给大家带来帮助。