SQLite in WinCE

SQLite를 윈도우즈 CE 플랫폼에서 실행 되도록 빌드 해보자.
윈도우즈 플랫폼은 그냥 빌드하면 되지만 CE 플랫폼에서는 몇 군데 수정을 해야 한다.

윈도우즈 CE용 SQLite 다운 받기 : http://sqlite-wince.sourceforge.net/ 파일을 사용하지 않고 sqlite 홈피에서 다운받아서 빌드했다.

http://www.sqlite.org/download.html에서 sqlite-source-3_6_22.zip 버전을 다운받아 빌드했다.

<< 정적인 SQLite 라이브러리 빌드 >>

1. "프로젝트 형식"은 스마트 장치 선택, "템플릿"은 Win32 스마트 장치 프로젝트 선택  

2. "플랫폼"은 STANDARDSDK_500 선택 ( CE 에뮬레이션에서 먼저 돌아가는지 테스트 하기 위해서)

3. "응용 프로그램 종류"는 "정적 라이브러리(S)"를 선택
  "추가 옵션"에서는 "미리 컴파일된 헤더(P)"는 체크를 해제후 빈 프로젝트를 만든다.

4. 다운로드 받은 sqlite 소스를 프로젝트에 추가한다.
  여기서 tclsqlite.c 파일은 프로젝트에서 제외 시킨다.

5, 프로젝트 -> 속성 -> 구성 속성 -> C/C++ -> 전처리기에 NO_TCL을 추가한다.
   TCL은 사용하지 않으므로 TCL 관련 해서 제외시킨다.  

6. 프로젝트 -> 구성 속성 --> 라이브러리 관리자 -> 일반 -> 출력파일에서  출력 라이브러리 이름을 수정한다. 아래와 같이 바꾼다.
릴리즈에서는 $(OutDir)\staticSQLite_R.lib
디버그에서는 $(OutDir)\staticSQLite_D.lib

7. 프로젝트 --> 속성 --> C/C++ --> 출력 파일 --> 프로그램 데이터베이스 파일이름   이름 수정.
디버거 : vc80.pdb --> staticsqlite_d.pdb
릴리즈: vc80.pdb --> staticsqlite_r.pdb

8. shell.c 파일을 수정한다.
빨간색 소스는 주석처리하고 #define FILENAME_MAX 1024 라인을 추가한다.

//shell.c

#if defined(_WIN32) || defined(WIN32)

//# include <io.h>

#define FILENAME_MAX 1024

#define isatty(h) _isatty(h)

#define access(f,m) _access((f),(m))

#else

/* Make sure isatty() has a prototype.

*/

extern int isatty();

#endif

 

#if defined(_WIN32_WCE)

/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()

 * thus we always assume that we have a console. That can be

 * overridden with the -batch command line option.

 */

//#define isatty(x) 1

#endif

9. 빌드후 라이브러리와 pdb 파일은 같은 폴더에 두도록 한다.

 

<< 샘플 프로그램 빌드 >>

샘플 프로그램 MyWord 프로젝트를 빌드해보자. 프로그램의 기능은 하나도 없고 SQLite가 정상적으로 실행되는지 체크하는 프로그램이다. 정상적으로 실행되면 customer.db 폴더가 생성된다.

프로젝트 타겟은 STANDARDSDK_500 (ARMV4I)와 STANDARDSDK_500 (x86) 두 개를 사용한다.

정적 라이브러리 빌드에서 만들어진 lib, pdb 파일은 샘플 프로그램의 common 폴더로 복사한다.

헤더 선언은 다음과 같다.

#include "common/sqlite3.h"


라이브러리는 프로젝트 구성이 아니라 소스에 추가한다.

#ifdef _ARM_

#ifdef _DEBUG

#pragma comment(lib, "./common/CESQLiteLib_armv4i_D.lib")

#else

#pragma comment(lib, "./common/CESQLiteLib_armv4i_R.lib")

#endif

#endif

 

#ifdef _X86_

#ifdef _DEBUG

#pragma comment(lib, "./common/CESQLiteLib_D.lib")

#else

#pragma comment(lib, "./common/CESQLiteLib_R.lib")

#endif

#endif

STANDARDSDK_500 (ARMV4I) 타겟은 _ARM_ 선언이, STANDARDSDK_500 (x86) 타겟은 _X86_ 선언을 사용한다.

TestSQL 코드를 추가하여 customer.db 파일이 정상 적으로 만들어지면 SQLite를 사용한 준비는 끝났다.

void TestSQL()

{

#if  1

    //파일 DB 사용시

    const char* dbfile = "customer.db";

#else

    //메모리 DB 사용시

    const char* dbfile = ":memory:";

#endif

 

    sqlite3*    pSQLite3 = NULL;  //SQLite DB 객체 저장 변수

    char*        szErrMsg = NULL;    //Error 발생시 메세지를 저장하는 변수

 

    //데이터베이스 열기 : 파일이 존재하지 않으면 생성한다.

    int    rst = sqlite3_open( dbfile, &pSQLite3 );

 

    char szTrace[300];

    if( rst )

    {

        sprintf( szTrace,"Can't Open database: %s\n", sqlite3_errmsg( pSQLite3 ));

        //OutputDebugStringA( szTrace );

        sqlite3_close( pSQLite3 );

        pSQLite3 = NULL;

    }

    else

    {

        //OutputDebugStringA( "\nDatabase opened!!\n");

 

        //테이블 생성

        rst = sqlite3_exec( pSQLite3, "CREATE TABLE member ( name TEXT(20), age INTEGER )", callback, 0, &szErrMsg);

 

        //데이터 삽입

        rst = sqlite3_exec( pSQLite3, "INSERT INTO member ( name, age ) values ( 'andy', 20 )", callback, 0, &szErrMsg);

 

        //데이터  질의

        rst = sqlite3_exec( pSQLite3, "SELECT * FROM member", callback, 0, &szErrMsg);

        if( rst == 0 )

        {

            MessageBox( NULL, L"gogogo", L"성공적으로 찾기까지 실행\", MB_OK );

        }

    }

}

정적 라이브러리 프로젝트 : CESQLiteLib.zip

샘플 프로젝트 : MyWord.zip

<참고, 펌>

Windows Mobile에서 SQLite 사용하기   
http://kr.blog.yahoo.com/nashorn74/1226324