Mengambil Data Dengan Panjang Tidak Diketahui

Banyak fungsi mengembalikan sejumlah besar data ke alamat yang disediakan sebagai salah satu parameter oleh aplikasi. Dalam semua kasus ini, operasi dilakukan dengan cara yang serupa, jika tidak identik, mode. Parameter yang menunjuk ke lokasi data yang dikembalikan akan menggunakan konvensi notasi di mana pb atau pv adalah dua karakter pertama dari nama parameter. Parameter lain akan memiliki pcb sebagai tiga karakter pertama dari nama parameter. Parameter ini mewakili ukuran, dalam byte, data yang akan dikembalikan ke lokasi pb atau pv. Misalnya, pertimbangkan spesifikasi fungsi berikut:

#include <windows.h>

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

Dalam contoh ini, pbData adalah penunjuk ke lokasi tempat data akan dikembalikan, dan pcbData adalah ukuran, dalam byte, dari data yang dikembalikan.

Catatan

Parameter pendamping ke parameter pcb terkadang dapat membawa awalan yang sedikit berbeda, seperti p atau pv. Selain itu, untuk parameter pendamping menggunakan kombinasi awalan pwsz dan pcch, parameter pcch adalah hitungan, dalam karakter (Unicode atau ASCII, sebagaimana berlaku), dari data yang dikembalikan.

 

Jika buffer yang ditentukan oleh parameter pbData tidak cukup besar untuk menyimpan data yang dikembalikan, fungsi mengatur kode ERROR_MORE_DATA (yang dapat dilihat dengan memanggil fungsi GetLastError ) dan menyimpan ukuran buffer yang diperlukan, dalam byte, dalam variabel yang ditunjukkan oleh pcbData.

Jika NULL dimasukkan untuk pbData dan pcbData bukan NULL, tidak ada kesalahan yang dikembalikan, dan fungsi mengembalikan ukuran, dalam byte, dari buffer memori yang diperlukan dalam variabel yang diacu oleh pcbData. Ini memungkinkan aplikasi menentukan ukuran, dan cara terbaik untuk mengalokasikan, buffer untuk data yang dikembalikan.

Catatan

Ketika NULL dimasukkan untuk pbData untuk menentukan ukuran yang diperlukan untuk memastikan bahwa data yang dikembalikan cocok dalam buffer yang ditentukan, panggilan kedua ke fungsi yang mengisi buffer dengan data yang diinginkan mungkin tidak menggunakan seluruh buffer. Setelah panggilan kedua, ukuran aktual data yang dikembalikan terkandung dalam pcbData. Gunakan ukuran ini saat memproses data.

 

Contoh berikut menunjukkan bagaimana parameter input dan output mungkin diimplementasikan untuk tujuan ini.

//-------------------------------------------------------------------
// 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);
}