的[out]
參數的語義對此非常明確。
是得到一個[out]
參數不應該的方法 - 不斷 - 看參數的值,直到它把東西就可以了。它是未初始化的內存。垃圾。事實上,如果你的方法是通過編組調用(inter-apartment或inter-process)來調用的,那麼垃圾就是你得到的:無論你的調用者在調用你的方法時可能放在哪裏,都被代理/存根;你永遠不會得到它。
如果客戶端/調用者在調用方法之前在參數上添加了某些內容,那肯定是內存泄漏(當然,它是一個像BSTR那樣的分配對象),但這是調用者的錯。所謂的方法不應該負責處理它。被調用的方法即使想要也不能處理泄漏。
如果要處理調用者可能傳入的任何值,則需要使用[in, out]
參數而不是[out]
。
最後一次警告:自動化客戶端(VBA,VBScript等)不支持[out]
參數。自動化將默默地處理任何[out]
參數,如果它是[in, out]
,這使你在一個尷尬的境地:由客戶端應用程序將被泄露放置在參數的任何值,你的方法不能做任何事情。
如果你計劃你的對象上正在使用的自動化客戶端,不使用[out]
參數。改爲使用[in, out]
,並確保在調用之前,檢查調用者是否在參數上放置了一個值。代理/存根總是會爲[in, out]
參數的兩種方式編組值。如果調用者在調用之前在參數上放置了一個值,則在寫入參數之前,您的方法負責釋放該值。
編輯:擴大對指針本身是NULL:
你能想到的檢查NULL,並返回E_INVALIDARG
如果它是空的,但我不會推薦它。
是非法的傳遞NULL作爲用於[out]
參數的指針值。即使您的代碼處理NULL值,如果調用被編組,編組人員也會觸發訪問衝突。編組人員必須在返回時訪問指向的值(將編組輸出存儲在其上),並且不會檢查null。
在您的特定情況下(調用語義是在給定情況下沒有任何內容可以返回),正確的過程是調用者始終提供一個指向存儲區的指針,並且調用的方法將值設置爲空值。像這樣:
// Caller
BSTR comment;
hr = obj->a_method(42, &comment);
// Callee
HRESULT a_method(value, BSTR *comment)
{
if (...)
{
//... I've decided we don't need to return a comment
*comment = NULL;
}
...
}
如果你真的想要你提到的純空指針語義,你可以;但您必須使用[ptr]
屬性標記該參數。據我所知,自動化客戶端不能很好地工作,你必須使用自定義編組器。如果您不希望使用自動化客戶端,這顯然是一種選擇。
您是否期望使用'a_method'作爲RPC? –
你的意思是,我是否期望在進程外服務器中使用它?目前我的服務器正在處理中,但我將來可能會開發一個oop版本。 –