Eclipse, MinGW, CDT 환경에서 C/C++과 MySQL 연동

2010/04/21 19:08
Eclipse에서 CDT 플러그인과 MinGW에서 지원하는 C/C++ 컴파일러를 통해 개발하는 방법에 대해서 소개했었다.
Eclipse Galileo에서 C,C++ 개발환경 구축하기 - CDT, MinGW

참고로 오래전에 MS Visual Studio 환경에서 MySQL과 연동하는 방법과 ActionScript 3.0 으로 만들어진 MySQL Driver에 대해 소개한 적이 있다.
MS Visual C++ 6.0 환경에서 MySQL 연동하는 방법
Actionscript 3 Mysql Driver

이 글은 Eclipse + MinGW 환경에서 C/C++로 MySQL과 연동하는 방법을 소개한다. MySQL 연동을 위해서 Eclipse환경을 선택한 이유는 기존 프로젝트들이 Java, Flash 로 제작되어서 하나의 툴에서 개발하고 싶은 욕구가 있기 때문이다. 하나의 Eclipse로 Java, PHP, C/C++, Flash 개발을 다할 수 있기 때문에 지원하는 각종 플러그인을 함께 공유할 수 있고 툴을 이리저리 이동할 필요도 없어진다.

Eclipse와 MinGW으로 개발환경을 구축한 만큼 그에 맞게 개발방식을 알아야 할 것이다.


1. MinGW Utils 설치

MinGW에서 지원하는 Utils을 다운로드 받아서 설치해야 한다. 이것이 필요한 이유는 reimp.exe 가 필요하기 때문이다. 자세한 내용은 다음에 설명한다.

다음 링크로 들어가서 아래 리스트에 MinGW Utilities > mingw-utils > mingw-utils-0.3 로 가면 mingw-utils-0.3.tar.gz 파일이 있다. 이것을 다운로드 받는다.

http://sourceforge.net/projects/mingw/files/

압축을 풀면 bin, doc 폴더가 있는데 이 두개 폴더를 복사해서 MinGW 설치폴더에 덮어씌우면 된다. 그것으로 설치 끝이다.


2. MySQL 라이브러리 설치
MySQL 서버가 이미 설치가 되어 있는 경우라고 가정한다. 일단 다음 링크로 가서 MySQL MSI 설치자를 다운로드 받는다.

http://dev.mysql.com/downloads/mysql

다운로드 받은수 설치시에 아래와 같은 Setup Type을 묻는 내용이 나오면 custom을 선택한다.

MySQL이 이미 설치되어 있거나 어떠한 경로라도 접속할 수 있는 환경이 이미 조성되어 있는 경우에는 Server를 굳이 설치할 필요가 없으므로 아래처럼 C개발시 필요한 파일만 설치가 되도록 설정한다.

아마도 C:/Program Files/MySQL/MySQL Server 5.1/ 내에 설치될 것이다. 그 안에는 include와 lib만 존재할 것이다. include는 c언어의 header 파일들이 존재할 것이다. 그리고 lib에는 MySQL에 접속하기 위한 각종 Lib파일들이 존재한다.


3. MySQL 연동을 위한 MinGW 컴파일러 라이브러리로 만들기
MySQL설치 폴더에 lib/opt/libmysql.lib 가 있다. 이것은 MySQL을 접속하기 위한 구현체 정의가 담겨있다. C,C++로 개발할 때는 이것을 참조해서 개발하고 컴파일해야 할것이다.

하지만 MinGW에서 제공하는 컴파일러는 .lib를 직접 사용할 수 없다. 그래서 대신 확장자가 .a인 MinGW 전용의 라이브러리로 변경해야하는데 앞서 소개한 MinGW Utils에 reimp.exe와 dlltool.exe가 그것을 가능하게 해준다.

먼저 CMD 창에 들어가서 다음과 같이 입력해본다.

C:\>cd C:/Program Files/MySQL/MySQL Server 5.1/lib/opt
C:\>reimp -d libmysql.lib
C:\>dlltool -d LIBMYSQL.def -D libmysql.dll -k -l libmysql.a

위처럼 명령후 opt 폴더안에 libmysql.a가 있는지 확인한다. 만약 없다면 opt폴더를 c:\ 하위로 옮겨보고 그 안에서 위 명령을 다시 해보길 바란다.

reimp -d libmysql.lib 는 LIBMYSQL.def를 만들어내는데 이것을 열어보면 라이브러리에 정의된 함수가 쭉 나열되어 있음을 확인할 수 있다. dlltool 은 이것을 이용해 libmysql.a를 뽑아낸다.

libmysql.a는 복사해서 MinGW의 lib폴더에 복사한다.

그리고 MySQL 설치폴더에 include은 mysql로 수정하고 MinGW의 include 내에 복사하면 아래처럼 사용할 수 있게 된다.

#include <mysql/mysql.h>


5. Eclipse에서 C프로젝트를 생성해 MySQL 접속해보기
이제 C로 MySQL에 접속하기 위한 준비는 완료했다. 이제 C프로젝트를 만들고 MySQL 접속하기 위한 간단한 예시를 만들어보자. File>New>C Project를 아래처럼 생성한다.



Project Explorer에 MySQLTest 프로젝트가 만들어졌을 것이다. src 폴더를 열어 MySQLTest.c를 다음 코드로 수정하자.


#define SOCKET int

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

#define DB_HOST "localhost 또는 아이피, 도메인"
#define DB_USER "DB 사용자 ID"
#define DB_PASS "DB 사용자 Password"
#define DB_NAME "DB 이름"

int main() {
	MYSQL *conn_ptr;
	conn_ptr = mysql_init(NULL);
	if(!conn_ptr) {
		printf("mysql_init failed!!\n");
		return 0;
	}

	conn_ptr = mysql_real_connect(conn_ptr, DB_HOST, DB_USER, DB_PASS, DB_NAME, 3306,(char *)NULL, 0);

	if(conn_ptr) {
		printf("연결이 성공 되었습니다.\n");
	} else {
		printf("연결에 실패했습니다.\n");
	}
	mysql_close(conn_ptr);
	return 1;
}

코드를 만들었으니 이제 MySQL 라이브러리를 사용한다는 컴파일 옵션을 주어야 한다. 방법은 다음과 같이 하면 되겠다.

이클립스 메뉴에서 Project > Properties로 들어간다. C/C++Build > Setting으로 들어가 Tool Setting 탭으로 누른다. 다음으로 MinGW C Linker > Libraries를 선택한다. 아래처럼 mysql을 등록한다. 이렇게 하면 컴파일시 -lmysql로 옵션을 주는 것과 같아진다.


Ctrl+B나 메뉴>Project>Build All을 선택해서 컴파일 해보자. 다음과 같처럼 컴파일이 정상적으로 나왔다면 성공한 것이다. 
 

**** Build of configuration Debug for project MySQLTest ****

**** Internal Builder is used for build               ****
gcc -O0 -g3 -Wall -c -fmessage-length=0 -osrc\MySQLTest.o ..\src\MySQLTest.c
gcc -oMySQLTest.exe src\MySQLTest.o -lmysql
Build complete for project MySQLTest
Time consumed: 578  ms. 

Ctrl+F11이나 Run > Run 을 해보자. 콘솔창에 아래처럼 나오면 성공한 것이다.


만약 위처럼 아무 메시지 없이 실행되지 않는 것처럼 보인다면 C:/Windows/System32 내에 libmysql.dll이 없는 것을 의심해본다.

실제로 CMD창을 열고 프로젝트의 Debug안에 있는 MySQLTest.exe를 CMD 창에 드래그해 붙여넣은 다음 Enter를 눌러 실행해보자. 아래처럼 "연결이 성공 되었습니다"라고 보이지 않고 그 아래처럼 libmysql.dll이 없다고 나오면 아래서 소개하는 두가지 방법으로 해결할 수 있다.



일단 libmysql.dll 이 있다고 가정한다면 아래 둘중에 하나를 선택해서 하면 된다.

  1. libmysql.dll을 C:/windows/System32에 복사한다.
  2. 프로젝트의 Debug폴더나 Release폴더(즉, exe 실행파일과 같은 경로)에 libmysql.dll을 복사한다.


dll과 함께 컴파일 처리하면 좋겠는데 아직 방법은 모르겠다.

libmysql.dll을 얻는 방법은 http://www.dll-files.com/ 에 접속해 libmysql.dll을 찾는다. libmysql.dll을 다운로드 받을 수 있는 페이지가 나오면 다른거 누르지 말고 아래 그림과 같은 Free download의 Download 버튼을 눌러 다운로드 받는다.



6. 테이블 생성, 선택, 삽입, 편집, 삭제 해보기
접속까지 했으니 응용하는 것은 누워서 떡먹기다. Create table, Select, Insert, Update, Delete 예제는 다음과 같다.

#define SOCKET int

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

#define DB_HOST "localhost 또는 아이피, 도메인"
#define DB_USER "DB 사용자 ID"
#define DB_PASS "DB 사용자 Password"
#define DB_NAME "DB 이름"

#define SQL_CREATE_TABLE "CREATE TABLE `mysql_api_test` (\
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,\
    `num` INT NULL ,\
    `string` VARCHAR( 20 ) NULL \
    ) TYPE = MYISAM ;"
#define SQL_INSERT_RECORD "INSERT INTO `mysql_api_test` ( `id` , `num` , `string` ) \
    VALUES (\
    NULL , '%d', '%s'\
    );"
#define SQL_SELECT_RECORD "SELECT * FROM `mysql_api_test`"
#define SQL_DROP_TABLE "DROP TABLE `mysql_api_test`"

int main() {
	MYSQL *connection=NULL, conn;
	MYSQL_RES *sql_result;
	MYSQL_ROW sql_row;
	int query_stat;
	int i;

	char query[255];

	mysql_init(&conn);

	// DB 연결
	connection = mysql_real_connect(&conn, DB_HOST, DB_USER, DB_PASS,DB_NAME, 3306,(char *)NULL, 0);
	if(connection==NULL) {
		fprintf(stderr, "Mysql connection error : %s", mysql_error(&conn));
		return 1;
	}

	// 테이블 생성
	query_stat=mysql_query(connection,SQL_CREATE_TABLE);
	if (query_stat != 0) {
		fprintf(stderr, "Mysql query error : %s", mysql_error(&conn));
		return 1;
	}

	// 레코드 삽입
	for(i=0;i<5;i++) {
		sprintf(query,SQL_INSERT_RECORD,100+i,"안녕하세요 지돌스타예요~");
		query_stat = mysql_query(connection, query);
		if (query_stat != 0) {
			fprintf(stderr, "Mysql query error : %s", mysql_error(&conn));
			return 1;
		}
	}

	// 셀렉트
	query_stat=mysql_query(connection,SQL_SELECT_RECORD);
	if (query_stat != 0) {
		fprintf(stderr, "Mysql query error : %s", mysql_error(&conn));
		return 1;
	}

	// 결과 출력
	sql_result=mysql_store_result(connection);
	while((sql_row=mysql_fetch_row(sql_result))!=NULL) {
		printf("%2s %2s %s\n",sql_row[0],sql_row[1],sql_row[2]);
	}
	mysql_free_result(sql_result);

	// 테이블 삭제
	query_stat=mysql_query(connection,SQL_DROP_TABLE);
	if (query_stat != 0) {
		fprintf(stderr, "Mysql query error : %s", mysql_error(&conn));
		return 1;
	}

	// DB 연결 닫기
	mysql_close(connection);
	return 0;
}


7. 정리하며
이미 많은 분들이 삽질(?)을 많이 해주셔서 비교적 쉽게 MySQL 개발 환경을 조성할 수 있었다. 뭔가 이런 환경에서 개발한다면 크로스 플랫폼 애플리케이션을 만드는데 도움이 될 것 같다. 관련된 정보를 찾아봐서 개발방법에 대해서 좀더 숙지해야할 필요가 있을 것 같다.


8. 참고글
Eclipse Galileo에서 C,C++ 개발환경 구축하기 - CDT, MinGW
MS Visual C++ 6.0 환경에서 MySQL 연동하는 방법
VC용 lib화일을 mingw용 라이브러리로 변환하기
MinGW로 Mysql plugin driver compile하는 방법
DLL 다운받기


글쓴이 : 지돌스타(http://blog.jidolstar.com/679)

저작자 표시 비영리 동일 조건 변경 허락

Development Settings , , , , , , ,

  1. 안녕하세요 궁금한점이있어서 그런데요
    너무 유용한글 감사합니다.

    현재 여기는 Eclipse C++를 사용해서 MySQL이랑 연동하고있는데
    궁금한게 Oracle이랑 연결하고싶을땐 어떻게 구현해야하나요
    제가 알기론 비슷한 방법으로 알고있는데
    궁금합니다~^^

  2. 그건 오라클 자체에서 지원해주겠지요.

  3. Blog Icon
    sdf

    설명이 쉽지는않네요
    특히 mysql server 5.5/include 폴더에서 h 파일들을 mingw 로 옴겨야 돼는데 그것도 설명안돼있고
    mysql.h 파일같은건 mysql server 5.5/include 에있는데

  4. 아~ 그러셨군요. 부족했다면 이해해 주세요. 그래도 이 정도면 친절한 편인데 ^^

  5. Blog Icon
    주희사랑

    지금 프로젝트를 VIM 환경을 이용하여 개발을 하고 있습니다.

    현재 구현중인 프로젝트에는 여러개의 모듈이 있고,
    각 모듈이 사용하는 별도의 LIB 관련 디렉토리가 있습니다.
    각 모듈 별로 makefile 을 둬서 모듈 및 라이브러리 단위로 빌드하였습니다.

    구조는

    : BIN프로젝트
    : ㄴ module-A : lib-A, B 사용
    : ㄴ module-B : lib-A, C 사용
    : ㄴ module-C : lib-C 사용

    : LIb프로젝트
    : ㄴ lib-A
    : ㄴ lib-B
    : ㄴ lib-C

    이와 같습니다.

    이와 같은 환경을 이클립스에서 사용할 수 있을까요?

  6. 그건 잘 모르겠습니다. 하지만 이클립스에도 충분히 사용할 수 있다고 생각해요.