2009-04-01 4 views
3

COM 인터페이스를 구현할 때 필자는 항상 성공시 out 매개 변수를 할당하지만 오류가 발생하더라도이를 수행해야합니까?COM 함수가 실패하더라도 매개 변수를 설정해야합니까?

HRESULT CDemo::Div(/*[in]*/ LONG a, /*[in]*/LONG b, /*[out,retval]*/ LONG* pRet) 
{ 
    if (pRet == NULL) 
     return E_POINTER; 

    if (b == 0) 
    { 
     *pRet = 0; // is this redundant? 
     return E_INVALIDARG; 
    } 

    *pRet = a/b; 
    return S_OK; 
} 

한때는 I는 출력 파라미터를 초기화하고 I 변수를 초기화하는 경우 I 메소드 내부를 변경하지 않을 경우는 그 값을 유지 것이라고 가정하지 않음으로써 코 비트이었다. 그러나 나는 .NET에서이 방법을 사용했으며 marshaller는 이것이 [out] 매개 변수라는 것을 알고 있기 때문에 호출 사이트에 놓은 초기 값을 무시하고 함수가 반환 된 후 가비지를 넣었습니다 (재미있는 디버깅이 아닌).

오류 초과 보상시에도 out 매개 변수에 할당하고 있습니까? 아니면 실제로해야합니까?


편집 :

ISmth *pSmth = NULL; 
pObj->GetSmth(&pSmth); // HRES is ignored 
if (pSmth) // Assumes that if GetSmth failed then pSmth is still NULL 
{ 
    pSmth->Foo(); 
    pSmth->Release(); 
} 

: 함수가 나는이 같은 코드 (sharptooth's post에서 예를 사용)을 종종 볼 (때로는 쓰기) 실패 할 경우 공식적으로 하나 PARAMS을 액세스하지 않아야에도 불구하고 이것은 비 정렬 화 코드에서 똑같이 작동하지만 (동일 thread apartment) marshaller가 관련되어 있으면 함수가 성공하면 반환 값만 설정할만큼 똑똑합니까?

+0

나는 그것이 중요하지 않아야한다고 생각한다. 호출하는 COM 클라이언트는 실패가 발생하면'out' 매개 변수를 보지 않아야합니다. –

답변

3

다른 대답은 잘못은 아니지만 매우 중요한 부분을 놓치게됩니다. 즉, 오류를 반환 할 COM 서버 HRESULT 은 모든 [out] 매개 변수를 NULL로 설정해야합니다 (MUST). 이것은 단순히 좋은 스타일의 문제 만은 아니며 COM에서 필요하며이를 준수하지 않으면 관련 마샬링이 발생할 때 임의의 충돌이 발생할 수 있습니다.

즉, * pRet = 0; 원래 코드에서 중복되지는 않지만 정확하고 필수적입니다.

+0

이 소유권 주장에 대한 참조를 제공 할 수 있습니까? – Motti

+0

Effective COM, 항목 19 : 항상 [out] 매개 변수를 초기화하십시오. COM 사양의 어딘가에 매장해야합니다 ... –

+0

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686638(v=vs.85).aspx –

3

통화가 실패 할 경우 발신자가 out 매개 변수 값을 사용하여 아무 것도 수행 할 수 없다는 규칙이 있습니다. 따라서 서버는 유효한 값을 제공하면 안되며 모든 자원의 소유권을 out 매개 변수로 전달해서는 안됩니다. 예를 들어

당신은이 서버가 ISmth** 변수 이전에 반환에에 AddRef() 호출 것으로 예상 것

HRESULT GetSmth([out] ISmth**); 

방법이있는 경우. 클라이언트가 반환 된 매개 변수 값을 사용할 수 없으므로 Release()을 호출하지 않아 오류 코드를 반환 할 경우 AddRef()을 호출하면 메모리 누수가 발생합니다.

1

100 % sharptooth와 (과) 동의합니까? 실패한 COM 호출의 경우 out 매개 변수에 리소스 소유권을 할당 할 수 없으며 할당하지 않아야합니다. 여기에는 메모리 할당 또는 COM 개체의 AddRefing이 포함됩니다.

그러나 나는 리소스 소유권을 전송하지 않기 때문에 순수한 매개 변수를 빈 값으로 설정하는 것은 잘못된 것이 없다는 것을 알 수 있습니다. 예를 들어, 코드 설정에 대해 기술적으로 불법적 인 것은 없습니다. 0을 가리 키도록 설정하십시오. 이는 pRet에 대한 자원 소유권을 넘겨주지 않으며 호출 성공 여부를 제대로 확인하지 않은 일부 호출자에게는 도움이됩니다.

관련 문제