Ошибка COM 0x80004003 (неверный указатель) доступ к контактам MS Outlook

Я являюсь кодом ATL, который использует интеллектуальные указатели COM для перебора контактов MS Outlook, и на некоторых ПК я получаю ошибку COM 0x80004003 («Неверный указатель») для каждого контакта. Тот же код отлично работает на других ПК. Код выглядит следующим образом:

_ApplicationPtr ptr;
ptr.CreateInstance(CLSID_Application);

_NameSpacePtr ns = ptr->GetNamespace(_T("MAPI"));
MAPIFolderPtr folder = ns->GetDefaultFolder(olFolderContacts);

_ItemsPtr items = folder->Items;
const long count = items->GetCount();

for (long i = 1; i <= count; i++)
{
    try
    {
        _ContactItemPtr contactitem = items->Item(i);
        // The following line throws a 0x80004003 exception on some machines
        ATLTRACE(_T("\tContact name: %s\n"), static_cast<LPCTSTR>(contactitem->FullName));
    }
    catch (const _com_error& e)
    {
        ATLTRACE(_T("%s\n"), e.ErrorMessage());
    }
}

Интересно, могут ли это быть причиной каких-либо других приложений/надстроек? Любая помощь приветствуется.


person Rob    schedule 22.05.2009    source источник
comment
Одна возможная проверка. Является ли contactitem когда-либо нулевым? Я бы так не думал, потому что вы заранее проверяете счет, но попробовать стоит.   -  person Matthew Flaschen    schedule 22.05.2009


Ответы (4)


FullName — это свойство, и вы выполняете операцию GET (вероятно, в IDL это выглядит примерно так: get_FullName([out,retval] BSTR *o_sResult)). Такая операция работает нормально с нулевыми значениями.

Я предполагаю, что умный указатель contactItem указывает на любой допустимый COM-объект. В таком случае операция форматирования, выполненная ATLTRACE, может вызвать проблему. Внутри он ведет себя, вероятно, как стандартная функция sprintf("",args...).

Чтобы избежать таких проблем, просто сделайте что-то вроде ниже:

ATLTRACE(_T("\tContact name: %s\n"),
_bstr_t(contactitem->FullName)?static_cast<LPCTSTR>(contactitem->FullName):"(Empty)")
person Aleksander Stankiewicz    schedule 27.05.2009

Просто предположение: может быть, поле «FullName» в адресной книге пусто, и поэтому указатель недействителен?

трудно сказать, потому что ваш код не указывает, какие COM-интерфейсы вы используете.

person Stefan    schedule 22.05.2009

Имеет ли это какое-то значение?

ATLTRACE(_T("\tContact name: %s\n"), static_cast<LPCTSTR>(contactitem->GetFullName()));
person ralphtheninja    schedule 11.06.2009

В моем примере вы форматируете значение NULL в правильное текстовое значение.

Если вопрос касается разницы между FullName (как свойство) и GetFullName() (как метод), то ответ отрицательный. Свойство и метод должны давать один и тот же результат. Иногда свойство может быть сопоставлено с другими методами, отличными от setXXX и getXXX. Этого можно добиться, используя определенный синтаксис в IDL (и фактически в TLB после компиляции IDL в TLB). Если свойство FullName не сопоставлено с методом GetFullName, вы получите другой результат.

Поэтому, пожалуйста, проверьте файл *.tlh после импорта какой-либо библиотеки типов в ваш проект...

person Aleksander Stankiewicz    schedule 15.06.2009