Reputation: 1577
I have a function say foo
which returns SAFEARRAY of COM pointers
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();
}
This is my 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)
now I have done this,
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>
}
Please help me fix this issue.
Upvotes: 1
Views: 490
Reputation: 15355
If your safe array contains IDisptach* your call to SafeArrayAccessDate returns an IDispatch**. In fact you get the start of the array of the first pointer.
Also you code to create the objects isn't very useful. You don't need to create the array of objects (and even there is a leak you don't free it again.
Just create one object at a time and assign it to the safe array. There is no need for a second pointer. Also there is a problem with your reference counting. AFAIK there is no need to call AddRef after you createdthe instance. Is is already locked. And you don't want a second lock.
Also you should always use QueryInterface to obtain a pointer of the given type you want to store (IDisptach), and again you need to call QueryInterface when you want to convert the IDispatch back into a IMyClass pointer.
Upvotes: 2