使用內容句柄進行伺服器開發
從伺服器程式開發的觀點來看,上下文控制代碼是不具類型的指標。 伺服器程式透過將上下文句柄指向記憶體或其他形式的存儲(例如磁碟上的檔案)來初始化上下文句柄。
例如,假設用戶端使用內容句柄來要求資料庫中記錄的一系列更新。 用戶端會在伺服器上呼叫遠端程式,並傳遞搜尋金鑰。 伺服器程式會搜尋資料庫的搜尋索引鍵,並取得相符記錄的整數記錄編號。 然後,伺服器可以將指標指向包含記錄編號的記憶體位置 void。 傳回時,遠端程式必須透過傳回值或其參數清單,以內容句柄的形式傳回指標。 每次呼叫遠端程式來更新記錄時,用戶端都必須將指標傳遞至伺服器。 在這些更新作業中,伺服器會將 void 指標轉換成整數的指標。
在伺服器程式將內容句柄指向內容數據之後,會將句柄視為已開啟。 包含 NULL 值的句柄會關閉。 伺服器會維護已開啟的上下文控制代碼,直到用戶端呼叫遠端程序來關閉它為止。 如果客戶端會話在句柄開啟時終止,RPC 執行階段會呼叫伺服器降級例程來釋放句柄。
下列代碼段示範伺服器如何實作內容句柄。 在此範例中,伺服器會維護用戶端使用遠端程式寫入的數據檔。 內容資訊是檔案句柄,可追蹤伺服器將寫入數據的檔案中目前的位置。 檔案句柄會封裝為參數清單中的內容句柄,以遠端過程調用。 結構包含檔名和文件句柄。 此範例的介面定義顯示在 使用內容句柄進行介面開發。
/* cxhndlp.c (fragment of file containing remote procedures) */
typedef struct
{
FILE* hFile;
char achFile[256];
} FILE_CONTEXT_TYPE;
RemoteOpen 函式會在伺服器上開啟檔案:
short RemoteOpen(
PPCONTEXT_HANDLE_TYPE pphContext,
unsigned char *pszFileName)
{
FILE *hFile;
FILE_CONTEXT_TYPE *pFileContext;
if ((hFile = fopen(pszFileName, "r")) == NULL)
{
*pphContext = (PCONTEXT_HANDLE_TYPE) NULL;
return(-1);
}
else
{
pFileContext = (FILE_CONTEXT_TYPE *)
MIDL_user_allocate(sizeof(FILE_CONTEXT_TYPE));
pFileContext->hFile = hFile;
// check if pszFileName is longer than 256 and if yes, return
// an error
strcpy_s(pFileContext->achFile, srlen(pszFileName), pszFileName);
*pphContext = (PCONTEXT_HANDLE_TYPE) pFileContext;
return(0);
}
}
RemoteRead 函式會讀取伺服器上的檔案。
short RemoteRead(
PCONTEXT_HANDLE_TYPE phContext,
unsigned char *pbBuf,
short *pcbBuf)
{
FILE_CONTEXT_TYPE *pFileContext;
printf("in RemoteRead\n");
pFileContext = (FILE_CONTEXT_TYPE *) phContext;
*pcbBuf = (short) fread(pbBuf, sizeof(char),
BUFSIZE,
pFileContext->hFile);
return(*pcbBuf);
}
RemoteClose 函式會關閉伺服器上的檔案。 請注意,伺服器應用程式必須將 NULL 指派給內容句柄,做為 close 函式的一部分。 這會通知伺服器存根和 RPC 執行時期函式庫,指出上下文控制代碼已被刪除。 否則,連線將保持開啟,最終會發生上下文終止。
void RemoteClose(PPCONTEXT_HANDLE_TYPE pphContext)
{
FILE_CONTEXT_TYPE *pFileContext;
if (*pphContext == NULL)
{
//Log error, client tried to close a NULL handle.
return;
}
pFileContext = (FILE_CONTEXT_TYPE *)*pphContext;
printf("File %s closed.\n", pFileContext->achFile);
fclose(pFileConext->hFile);
MIDL_user_free(pFileContext);
// This tells the run-time, when it is marshalling the out
// parameters, that the context handle has been closed normally.
*pphContext = NULL;
}
注意
雖然預期用戶端會將有效的內容句柄傳遞至具有 [in, out] 方向屬性的呼叫,但 RPC 不會拒絕此方向屬性組合 NULL 內容句柄。 NULL 上下文處理程序會以 NULL 指標的形式傳遞給伺服器。 應該寫入包含 [in, out] 內容句柄之呼叫的伺服器程式代碼,以避免收到 NULL 指標時發生存取違規。