共用方式為


使用內容句柄進行伺服器開發

從伺服器程式開發的觀點來看,上下文控制代碼是不具類型的指標。 伺服器程式透過將上下文句柄指向記憶體或其他形式的存儲(例如磁碟上的檔案)來初始化上下文句柄。

例如,假設用戶端使用內容句柄來要求資料庫中記錄的一系列更新。 用戶端會在伺服器上呼叫遠端程式,並傳遞搜尋金鑰。 伺服器程式會搜尋資料庫的搜尋索引鍵,並取得相符記錄的整數記錄編號。 然後,伺服器可以將指標指向包含記錄編號的記憶體位置 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 指標時發生存取違規。