3

我是一些 ATL 代码,它使用智能 COM 指针遍历 MS Outlook 联系人,在某些 PC 上,我收到每个联系人的 COM 错误 0x80004003(“无效指针”)。相同的代码在其他 PC 上运行良好。代码如下所示:

_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());
    }
}

我想知道是否有任何其他应用程序/加载项可能导致这种情况?欢迎任何帮助。

4

4 回答 4

1

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)")
于 2009-05-27T20:32:33.683 回答
0

在我的示例中,您将 NULL 值格式化为正确的文本值。

如果问题是关于 FullName(作为属性)和 GetFullName()(作为方法)之间的区别,那么答案是否定的。属性和方法应该给出相同的结果。有时属性可以映射到不同的方法,然后是 setXXX 和 getXXX。它可以通过在 IDL 中使用一些特定的语法来实现(实际上是在将 IDL 编译为 TLB 之后的 TLB 中)。如果属性 FullName 未映射到方法 GetFullName,那么您将获得不同的结果。

因此,请在将某些类型库导入您的项目后检查文件 *.tlh...

于 2009-06-15T21:57:40.450 回答
0

这有什么区别吗?

ATLTRACE(_T("\tContact name: %s\n"), static_cast<LPCTSTR>(contactitem->GetFullName()));
于 2009-06-11T21:43:12.683 回答
0

只是猜测:也许通讯录中的“FullName”字段为空,这就是指针无效的原因?

很难说,因为您的代码没有指明您正在使用哪些 COM 接口。

于 2009-05-22T07:22:21.543 回答