WinCE 레코드 읽기 쓰기와 버퍼 (윈도우 CE 할당, 구조체)

WinCE 레코드 읽기 쓰기와 버퍼 (윈도우 CE 할당, 구조체)


레코드 읽기와 버퍼

원하는 레코드로 데이터베이스 포인터를 이동한 후에는 레코드를 읽거나 쓸 수 있다. 다음 WinCE 함수로 레코드를 읽는다.


첫 번째 파라미터는 열려있는 데이터베이스 핸들이다. lpcPropID 파라미터는 그다음 파라미터인 rgPropID가 가리키는 CEPROPID 구조체의 요소 개수 포인터다. 이 파라미터 두 개로 레코드에서 읽을 속성을 지정한다. lpcPropID, rgPropID를 사용하는 법은 두 가지가 있다.


레코드 속성 중 몇 개만 선택해 읽고 싶을 때는 원하는 속성 ID를 지정해 CEPROPID 구조체 배열을 초기화하고 lpcPropID가 가리키는 변수에 구조체 개수를 설정한다. 함수가 반환되면 정수와 같은 데이터형일 때는 CEPROPID 구조체에 삽입될 것이다.

가변 길이 문자열이나 blob 타입이라면 lplpBuffer가 가리키는 WinCE 버퍼로 반환된다.


1
2
3
4
5
CEOID CeReadRecordPropsEx (HANDLE hDbase, DWORD dwFlags,
                           LPWORD lpPropID,
                           CEPROPID *rgPropID, LPBYTE *lplpBuffer,
                           LPDWORD lpcbBuffer,
                           HANDLE hHeap);
cs


CeReadRecordPropsEx로 레코드를 읽는 작업은 상당한 오버헤드가 있으므로 한 번 호출했을 때 레코드에서 필요한 모든 속성을 읽는 것이 제일 나은 방법이다.


이렇게 하려면 WinCE의 rgPropID에 NULL을 설정하면 된다. 함수가 반환되면 lpcPropID가 가리키는 변수에는 반환되는 속성 개수가 담기고 레코드의 모든 속성이 버퍼로 반환된다.


winice 레코드 구조체 버퍼


버퍼에는 함수가 생성한 CEPROPID 구조체 배열이 담기고, 바로 뒤에는 CEPROPID 배열에 직접 저장되지 않는 데이터인 blob이나 문자열과 같은 속성이 담긴다.


CeReadRecordPropsEx는 편리한 기능을 한 가지 제공한다.


WinCE의 dwFlags 파라미터에 CEDB_ALLOWREALLOC를 설정하면 결과 값이 들어가는 버퍼 크기를 자동으로 증가시킨다. 물론 이 작업을 하려면 함수에 전달한 버퍼가 스택이나 정적 데이터 영역이어서는 안 된다. 로컬 힙이나 개별 힙에 할당받은 버퍼여야 한다.


사실 CEDB_ALLOWREALLOC 플래그를 사용하면 함수에 버퍼를 전달할 필요도 없고 버퍼 포인터를 0으로 설정한다. 그러면 함수가 알아서 버퍼를 할당한다.


버퍼 파라미터는 버퍼의 포인터가 아니라 버퍼를 가리키는 포인터 주소라는 점을 주의한다. 이런 식의 포인터 사용은 사실 꽤 골치 아프다. 함수 실행의 결과 버퍼가 재할당될 수 있고 그것은 곧 버퍼 주소가 바뀜을 의미한다.


즉, 함수가 버퍼를 변경할 수 있으므로 항상 함수가 반환하는 버퍼 포인터를 써야 한다. 또한, 사용한 후 버퍼를 해제하는 일도 해야 한다. 심지어 함수가 어떤 이유로 실패한 경우에도 버퍼가 이동했거나 해제됐을 수 있다. 읽기 작업을 한 후에 버퍼 포인터가 0이 아니라면 반드시 해제하는 작업을 해야 한다.

앞의 설명으로 짐작했겠지만 hHeap 파라미터를 사용하면 CeReadRecordPropsEx가 버퍼를 재할당할 때 로컬 힙 대신 다른 힙을 사용할 수 있게 할 수 있다. 로컬 힙을 사용하고 싶으면 hHeap에 0을 넘기면 된다.


다음 WinCE 코드는 레코드의 모든 속성을 읽고 구조체에 데이터를 복사한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
int ReadDBRecord (HANDLE hDB, DATASTRUCT *pData, HANDLE hHeap) {
    WORD wProps;
    CEOID oid;
    PCEPROPVAL pRecord;
    PBYTE pBuff;
    DWORD dwRecSize;
    int i;
 
    // 레코드의 모든 속성을 읽음
    pBuff = 0// 함수가 버퍼를 할당하게 설정
 
    oid = CeReadRecordPropsEx (hDB, CEDB_ALLOWREALLOC,
                               &wProps, NULL&(LPBYTE)pBuff,
                               &dwRecSize, hHeap);
 
    // 읽기가 실패하면
    if (oid == 0)
        return 0;
 
    // 레코드에서 구조체로 데이터 복사
    // 배열의 순서는 정의되어 있지 않음
    memset (pData, 0size(DATASTRUCT)); // 반환받을 구조체를 0으로 채움
    pRecord = (PCEPROPVAL)pBuff;         // CEPROPVAL 배열을 가리키는 포인터
 
    for (i = 0; i < wProps; i++) {
        switch (pRecord->propped) {
        case PID_NAME:
            lstrcpy (pData->szName, pRecord->val.lpwstr);
            break;
 
        case PID_TYPE:
            lstrcpy (pData->szType, pRecord->val.lpwstr);
            break;
 
        case PID_SIZE:
            pData->nSize = pRecord->val.iVal;
            break;
        }
 
        pRecord++;
    }
 
    if (hHeap)
        HeapFree (hHeap, 0, pBuff);
    else
        LocalFree (pBuff);
}
cs


이 함수는 모든 레코드 속성을 읽으므로 CeReadRecordPropsEx가 CEPROPVAL 구조체의 배열을 생성한다.


이들 구조체의 순서는 정의되어 있지 않으므로 구조체에 채울 데이터를 찾는 과정을 거쳐야 한다. 모든 데이터를 읽은 후에는 HeapFree나 LocalFree를 호출해 CeReadRecordPropsEx가 반환한 버퍼를 해제한다.


모든 레코드가 모두 같은 속성을 담고 있는 것은 아니다. CEPROPID 배열을 정의해 레코드에 특정 속성을 요청했으나 해당 속성이 존재하지 않을 수도 있다.


이런 경우 WinCE의 CeReadRecordPropsEx는 CEPROPID 구조체의 wFlags 필드에 CEDB_PROPNOTFOUND를 설정한다. CeReadRecordPropsEx를 호출할 때 읽을 속성을 지정했다면 항상 이 플래그를 점검해야 한다. 앞의 예제에서는 모든 속성을 요청했다. 이런 경우 속성이 존재하지 않으면 CEPROPID 구조체가 반환되지 않는다.


WinCE 레코드 읽기 쓰기와 버퍼 (윈도우 CE 할당, 구조체)


레코드 쓰기

다음 함수로 레코드를 쓴다.


1
2
CEOID CeWriteRecordProps (HANDLE hDbase, CEOID oidRecord,
                          WORD cPropID, CEPROPVAL *rgPropVal);
cs


첫 번째 파라미터는 열려 있는 데이터베이스 핸들이다. oidRecord 파라미터는 쓸 레코드의 객체 ID다.


레코드를 수정하는 것이 아니라 새로운 레코드를 쓰려면 oidRecord를 0으로 설정한다. cPropID 파라미터는 rgPropVal이 가리키는 속성 ID 구조체 배열의 요소 개수를 지정한다. rgPropVal 배열에는 레코드에서 고치거나 데이터 쓰기를 할 속성을 지정하면 된다.


출처 : 윈도우 임베디드 CE 6.0 프로그래밍

WinCE 레코드 읽기 쓰기와 버퍼 (윈도우 CE 할당, 구조체)

이 글을 공유하기

댓글(0)

Designed by JB FACTORY