알 수 없는 길이의 데이터 검색

많은 함수는 애플리케이션에서 매개 변수 중 하나로 제공된 주소에 잠재적으로 많은 양의 데이터를 반환합니다. 이러한 모든 경우에서 작업은 동일하지 않은 경우 유사한 방식으로 수행됩니다. 반환된 데이터의 위치를 가리키는 매개 변수는 pb 또는 pv가 매개 변수 이름의 처음 두 문자인 표기법 규칙을 사용합니다. 다른 매개 변수에는 매개 변수 이름의 처음 세 문자로 pcb가 있습니다. 이 매개 변수는 pb 또는 pv 위치에 반환될 데이터의 크기(바이트)를 나타냅니다. 예를 들어 다음 함수 사양을 고려합니다.

#include <windows.h>

BOOL WINAPI SomeFunction(
  PCCRL_CONTEXT pCrlContext,  // in
  DWORD dwPropId,             // in
  BYTE *pbData,               // out
  DWORD *pcbData              // in/out
);

이 예제에서 pbData 는 데이터가 반환되는 위치에 대한 포인터이며 pcbData 는 반환된 데이터의 크기(바이트)입니다.

참고

pcb 매개 변수에 대한 도우미 매개 변수는 p 또는 pv와 같은 약간 다른 접두사로 전달될 수 있습니다. 또한 접두사 pwsz와 pcch의 조합을 사용하는 도우미 매개 변수의 경우 pcch 매개 변수는 반환된 데이터의 개수(유니코드 또는 ASCII)입니다.

 

pbData 매개 변수로 지정된 버퍼가 반환된 데이터를 저장할 만큼 크지 않은 경우 함수는 ERROR_MORE_DATA 코드(GetLastError 함수를 호출하여 볼 수 있음)를 설정하고 필요한 버퍼 크기를 pcbData가 가리키는 변수에 바이트 단위로 저장합니다.

nULLpbData에 대한 입력이고 pcbDataNULL이 아니면 오류가 반환되지 않으며 함수는 pcbData가 가리키는 변수에 필요한 메모리 버퍼의 크기를 바이트 단위로 반환합니다. 이를 통해 애플리케이션은 반환된 데이터에 대한 버퍼의 크기와 가장 좋은 할당 방법을 결정할 수 있습니다.

참고

반환된 데이터가 지정된 버퍼에 맞는지 확인하는 데 필요한 크기를 결정하기 위해 pbData대한 NULL 입력인 경우 버퍼를 원하는 데이터로 채우는 함수에 대한 두 번째 호출은 전체 버퍼를 사용하지 않을 수 있습니다. 두 번째 호출 후 반환된 데이터의 실제 크기는 pcbData에 포함됩니다. 데이터를 처리할 때 이 크기를 사용합니다.

 

다음 예제에서는 이 목적을 위해 입력 및 출력 매개 변수를 구현하는 방법을 보여줍니다.

//-------------------------------------------------------------------
// Copyright (C) Microsoft.  All rights reserved.
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

void MyHandleError(char *s);

void main()
{

// Set up SomeFunction variables.
PCCRL_CONTEXT pCrlContext; // Initialized elsewhere.
DWORD dwPropId;            // Initialized elsewhere.
DWORD cbData;
BYTE  *pbData;

// Call SomeFunction to set cbData, the size of 
// the buffer needed for pbData.
if(SomeFunction(
     pCrlContext, 
     dwPropId, 
     NULL, 
     &cbData))
{
       printf("The function succeeded.\n");
}
else
{

// The function call failed. Handle the error.
       MyHandleError("Function call failed.");
}

// The call succeeded; the size for the needed buffer, in bytes, 
// now resides in cbData.

// Malloc memory for the size of the message.
if(pbData = (BYTE*)malloc(cbData))
{
   printf("Memory has been allocated.\n");
}
else
{

   // The allocation failed. Write an error message and exit.
   MyHandleError("Malloc operation failed. ");
}

// The space for the buffer has been allocated.
// Call SomeFunction to fill the buffer with the data.
if(SomeFunction(
      pCrlContext, 
      dwPropId, 
      pbData, 
      &cbData))
{
       printf("The function succeeded.\n");
}
else
{

   // The second function call failed. Handle the error.
   MyHandleError("The second call to the function failed.");
}

// The function succeeded; the data is now in the buffer
// pointed to by pbData. Note that cbData is
// updated with the actual size of the data returned. Use this size 
// to process bytes of pbData.

// When you have finished using the allocated memory, free it.
free(pbData);

} // End of main

//  This example uses the function MyHandleError, a simple error
//  handling function, to print an error message to the 
//  standard error (stderr) file and exit the program. 
//  For most applications, replace this function with one 
//  that does more extensive error reporting.
void MyHandleError(char *s)
{
    fprintf(stderr,"An error occurred in running the program.\n");
    fprintf(stderr,"%s\n",s);
    fprintf(stderr,"Error number %x.\n",GetLastError());
    fprintf(stderr,"Program terminating.\n");
    exit(1);
}