Click here to Skip to main content
11,925,381 members (60,635 online)
Rate this:
Please Sign up or sign in to vote.
See more: C++ ATL
Dear Friends!
I have problem while working with ATL(VS2008, C++).
I must use SAFEARRAY(IMyObject*)* parameters in idl file.
If SAFEARRAY(double)*, then use the CComSafeArray..., but for interfaces or my structures, I don't know how to solve.
Thank you in advanced.

The idl file is...
interface IMyObj2;
typedef struct SMyObj2{
    IMyObj2 * iobject;
	helpstring("IMyObj2 Interface"),
interface IMyObj2 : IUnknown{
	[propget, helpstring("property ID")] 
	HRESULT ID([out, retval] LONG* pVal);
	[propput, helpstring("property ID")] 
	HRESULT ID([in] LONG newVal);

	helpstring("IArrayMan3 Interface"),
interface IArrayMan3 : IUnknown{
	[helpstring("method GetArray")] 
	HRESULT _stdcall GetArray2(SAFEARRAY(SMyObj2)* pArray);
	[helpstring("method PutArray")] 
	HRESULT _stdcall PutArray2(SAFEARRAY(SMyObj2) pArray);

C++ file...
	CComSafeArray<IUnknown*> ppp;//.Compile Okay.
//	CComSafeArray<SMyObj2, VT_VARIANT> arr;//.Compile Error
//      CComSafeArray<IMyObj2*> ttt;//.Compile Error
	return S_OK;
Posted 18-Sep-12 23:06pm

1 solution

Rate this: bad
Please Sign up or sign in to vote.

Solution 1

First of all it is nessesary to get an info from type library using IRecordInfo interface:
GUID GUID_SMyObj2 = __uuidof(SMyObj2);
CComPtr<IRecordInfo> srecnfo;
hr = GetRecordInfoFromGuids(LIBID_MyLib /*here is your type lib identifier*/, 1, 0, 0, GUID_SMyObj2, &srecnfo);
  _com_issue_errorex(hr, NULL, IID_NULL);
If this part will be successful, then it is possible to create a safearray or custom type:
const LONG l_bound = 0, u_bound = 2;
LPSAFEARRAY lpSMyObj2 = SafeArrayCreateVectorEx(VT_RECORD, l_bound,
  u_bound - l_bound + 1, srecnfo);
  _com_issue_errorex(E_FAIL, NULL, IID_NULL);
or access and use existing:
//LPSAFEARRAY lpSMyObj2 got from somewhere
//getting bounds of array
  LONG l_bound = 0, u_bound = 0;
  HRESULT hr1 = SafeArrayGetLBound(lpSMyObj2, 1, &l_bound);
  HRESULT hr2 = SafeArrayGetUBound(lpSMyObj2, 1, &u_bound);
  if(FAILED(hr1) || FAILED(hr2) )
      // handle an error
     SMyObj2 * pSMyObj2 = NULL;
     HRESULT hr = SafeArrayAccessData(lpSMyObj2, (void**)&pSMyObj2);
       _com_issue_errorex(hr, NULL, IID_NULL);
  // modifying data if needed
  for(int i = l_bound; i <= u_bound - l_bound; i++)
    // do something with pSMyObj2[i].iobject
  // Releasing an array
  hr = SafeArrayUnaccessData(lpSMyObj2);
    _com_issue_errorex(hr, NULL, IID_NULL);
Please see[^] for more details
Mem 9021960 19-Sep-12 6:05am
Very thanks!
But Isn't there the method using template class such that CComSafeArray?
And if client program need the SAFEARRAY(IMyObj*)* parameters, is there any problems?
skydger 19-Sep-12 7:05am
As far as I know, CComSafeArray uses VARIANT subsets of data, but not user defined. Besides it is a template wrapper class of SAFEARRAY and could not be flexible enogh for all the cases. So I think that using it with user defined types is little bit tricky. But maybe there is a solution to do so.

As for your question about using SAFEARRAY(IMyObj*)* instead of structure: it is the same as described, and it is simplier, because you need to create instances only (CoCreateInstance(...)) and release them.
Mem 9021960 19-Sep-12 7:22am
Dear Mr.skydger! I see.
As you see, I'm beginner at COM technology.
Thank you for your kindly help.
I often want your many help.
skydger 19-Sep-12 8:00am
Sure, if it will be possible for me :)
I don't know, what is the structure of that interface (IMyObj2), but sometimes it is more convenient for me to create custom array interface (for example IMyObj2Collection) but not the safearray. If I need not just array of custom types, but something like map<,>.
Mem 9021960 19-Sep-12 20:29pm
Of course, I made the three array structure, it is IMyObj2**, IMyObj2Collection*, SAFEARRAY(IMyObj2*)*.
The two methods using IMyObj2** and IMyObj2Collection was completed already.
But required items has SAFEARRAY(IMyObj2*)*.
IMyObj2's structure is simple.
For example, Point structure(double x, double y,...).
And if client program is coded by C#, What happens?
skydger 20-Sep-12 15:15pm
It is as implementation of classes in C#.
Please see the following article:

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy | Mobile
Web04 | 2.8.151126.1 | Last Updated 19 Sep 2012
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100