2009-09-15 3 views
8

Методы COM-интерфейсов могут возвращать различные значения HRESULT для передачи недопустимых значений аргументов. Когда я верну E_POINTER и когда E_INVALIDARG?Когда возвращается E_POINTER и когда E_INVALIDARG?

Как я понимаю, если метод получает индекс в инкапсулированной коллекции, а это за пределами E_INVALIDARG. Если метод получает указатель Interface**, где он предназначен для хранения указателя на вновь созданный объект, который является E_POINTER.

HRESULT CImpl::GetItem(long index; Interface** result) 
{ 
    if(result == 0) { 
     return E_POINTER; 
    } 
    if(index < 0 || index >= internalArray.size()) { 
     return E_INVALIDARG; 
    } 
    *result = CreateWrapperObject(internalArray[index]); 
    return S_OK; 
} 

Но что, если он получает WCHAR* буфер с именем файла в качестве «в» параметра и это WCHAR* равна нулю? Это E_POINTER или E_INVALIDARG?

Или метод получает указатель на какую-либо структуру и, как ожидается, заполняет структуру через этот указатель, и этот указатель имеет значение null - это E_POINTER или E_INVALIDARG?

HRESULT CImpl::SaveToFile(WCHAR* fileName) 
{ 
    if(fileName == 0) { 
     return // what to return here? 
    } 
    //... do actual work here 
} 

HRESULT CImpl::GetAttributes(Attributes* to) 
{ 
    if(to == 0) { 
     return // what to return here? 
    } 
    attributes->IsCool = getIsCool(); 
    attributes->Color = RGB(0, 255, 0); 
    return S_OK; 
} 

Каковы правила, когда для возврата E_POINTER и когда E_INVALIDARG при проверке параметров типа указатель?

ответ

9

Вы возвращаетесь E_POINTER, когда ссылка на указатель на из параметра равно нулю, это считают код ошибки, который указывает на ошибку в программе или в слое-взаимодействия.

Вы возвращаете E_INVALIDARG, когда на уровне приложения присутствует параметр, например, вне диапазона или параметр, который сталкивается друг с другом.

В вашем случае в SaveToFile(...) вы должны вернуться E_INVLIADARG, так как он не является допустимым, чтобы передать пустое имя файла, а в GetAttributes(...) вы должны вернуть E_POINTER (если это из пар), потому что вы не можете заполнить значение.

И да, мы все L-O-V-E com :)

+0

Есть ли у вас ссылки на doc? – Constantin

+0

Согласовано. Я бы очень хотел увидеть ссылку MSDN для этого. Вышеизложенное имеет какой-то смысл, но было бы неплохо иметь каноническую опровержение. –

+0

Я не уверен, что этот ответ правильный. Например, в VS2010 '' в реализации 'AtlSetChildSite()' E_POINTER' возвращается, если параметр 'punkChild' равен' NULL', вместо этого в соответствии с этим ответом (если я правильно понял), 'E_INVALIDARG 'должен был быть возвращен в этом случае. Я считаю, что ATL является хорошим источником хороших методов программирования COM, поэтому, возможно, «E_POINTER» должен быть возвращен в общих случаях недопустимых (например, «NULL') указателей. Но, честно говоря, я тоже не уверен, и я согласен, что официальная ссылка MSDN будет хорошей. –