擷取未知長度的資料
許多函式會將大量的資料傳回至應用程式提供作為其中一個參數的位址。 在所有這些情況下,作業會以類似的方式執行,如果不相同,則為 。 指向傳回資料位置的參數會使用標記法慣例,其中 pb 或 pv 是參數名稱的前兩個字元。 另一個參數將具有作為參數名稱的前三個字元。 此參數代表將傳回至 pb 或 pv 位置的資料大小,以位元組為單位。 例如,請考慮下列函式規格:
#include <windows.h>
BOOL WINAPI SomeFunction(
PCCRL_CONTEXT pCrlContext, // in
DWORD dwPropId, // in
BYTE *pbData, // out
DWORD *pcbData // in/out
);
在此範例中, pbData 是傳回資料的位置指標,而 bsData 是傳回資料的大小,以位元組為單位。
注意
將隨附參數隨附于不同參數,例如 p 或 pv。有時可能會有一些微不同的前置詞。 此外,針對使用前置詞 pwsz 和 pcch 的組合的隨附參數,pcch 參數是傳回資料的字元 (Unicode 或 ASCII中的計數,如適用) 。
如果 pbData 參數指定的緩衝區不夠大,無法保存傳回的資料,函式會將ERROR_MORE_DATA程式碼 (藉由呼叫 GetLastError 函式) ,並將所需的緩衝區大小以位元組為單位儲存在 由) 的變數中。
如果 Null 是 pbData 的輸入, 且不會 傳回 任何錯誤,而且函式會傳回 由其指向之變數中所需記憶體緩衝區的大小,以位元組為單位。 這可讓應用程式判斷傳回資料的緩衝區大小,以及配置的最佳方式。
注意
當pbData輸入Null以判斷所傳回資料符合指定緩衝區所需的大小時,第二次呼叫會將所需的資料填入緩衝區時,可能不會使用整個緩衝區。 第二次呼叫之後,傳回的資料實際大小會包含在 azureData中。 處理資料時,請使用此大小。
下列範例示範如何針對此目的實作輸入和輸出參數。
//-------------------------------------------------------------------
// 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);
}