1

我有一个函数说它foo返回 COM 指针的 SAFEARRAY

SAFEARRAY* foo()
{
    IMyClassPtr *objs = (IMyClassPtr*)callock(n, sizeof(IMyClassPtr));
    CComSafeArray<IDispatch*> sa(n);

    for(UINT index = 0; index < n; index++)
    {
        objs[index].CreateInstance(CLSID_MyClass);
        (objs[index])->AddRef();            

        objs[index]->put_X(index);
        objs[index]->put_Y(index+10);

        sa.SetAt(index, objs[index]);
    }

    return sa.Detach();
}

这是我的MyClass

class ATL_NO_VTABLE CMyClass :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CMyClass, &CLSID_MyClass>,
    public IDispatchImpl<IMyClass, &IID_IMyClass, &LIBID_mylibAlias, /*wMajor =*/ 1, /*wMinor =*/ 0>
{
public:
    CMyClass();
    virtual ~CMyClass();

DECLARE_REGISTRY_RESOURCEID(IDR_MyClass)


BEGIN_COM_MAP(CMyClass)
    COM_INTERFACE_ENTRY(IMyClass)
    COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()



    DECLARE_PROTECT_FINAL_CONSTRUCT()

    HRESULT FinalConstruct()
    {
        return S_OK;
    }

    void FinalRelease()
    {
    }
protected:
    ULONG x;
    ULONG y;
public:
    STDMETHOD(get_X)(ULONG* pVal);
    STDMETHOD(put_X)(ULONG newVal);
    STDMETHOD(get_Y)(ULONG* pVal);
    STDMETHOD(put_Y)(ULONG newVal);
};

OBJECT_ENTRY_AUTO(__uuidof(MyClass), CMyClass)

现在我已经做到了,

SAFEARRAY* sa;
IMyClassPtr* objs;
sa = foo();

if(SUCCEEDED(SafeArrayAccessData(sa, (void**)&objs)))
{
    // At this point, when I debug at the autos window objs contains some value
    // and I can see this message also
    // <No type information available in symbol file for oleaut32.dll>
}

请帮我解决这个问题。

4

1 回答 1

2

如果您的安全数组包含 IDispatch*,您对 SafeArrayAccessDate 的调用将返回 IDispatch**。事实上,你得到了第一个指针数组的开始。

您创建对象的代码也不是很有用。您不需要创建对象数组(即使存在泄漏也不会再次释放它。

一次只创建一个对象并将其分配给安全数组。不需要第二个指针。您的引用计数也存在问题。AFAIK 创建实例后无需调用 AddRef 。是已经被锁定。而且你不想要第二把锁。

此外,您应该始终使用 QueryInterface 来获取要存储的给定类型的指针 (IDisptach),并且当您想将 IDispatch 转换回 IMyClass 指针时,您需要再次调用 QueryInterface。

于 2015-08-11T06:19:17.707 回答