Solved

URGENT, I need an answer to this COM question

Posted on 2002-05-07
12
403 Views
Last Modified: 2008-02-01
I have created a simple object using the ATL. Within this object I have two contained or "delegated" objects, Obj1 and Obj2.

These "inner" objects need to communicate with one another. Now here is the problem, within a method of Obj1 I perform the following;



     CComQIPtr<IObj2, &IID_IObj2> pobj2 (GetControllingUnknown());


The above code fails because GetControllingUnknown() returns Obj1's OWN IUnknown pointer.

So I tried the following


CComQIPtr<IObj2, &IID_IObj2> pobj2 (m_pOuterUnknown);


This code asserts because m_pOuterUnknown is actually the reference count of Obj1 (if it's not an aggregate thats what it contains)

Is it not possible to query for another interface in contained objects? I cannot determine how to get the "outer" objects IUnknown.

0
Comment
Question by:johndixson
  • 6
  • 2
  • 2
  • +2
12 Comments
 
LVL 9

Expert Comment

by:BeyondWu
ID: 6995754
>>>These "inner" objects need to communicate with one another.

Why the two inner objects need to communicate? I think each inner objects is invisible for each other. If you want to exchange some information you can through the outer object, because only the outer object know there are two inner object, but the inner object should have some interfaces that let you exchange info inherent.

So, I think you can add some global data or data member in your own CMYComModule _Module; to exchange info.
Or you can provide some interfaces or functions to let the user call it and exchange info between two inner object, because only the outer object know the detail of inner object.

Hope this can help you!
0
 
LVL 6

Expert Comment

by:snoegler
ID: 6995998
You speak of "contained objects", i.e. not aggregates? GetControllingUnknown() works only in aggregated objects, so you can't use it in this context.

You can, though, add another method to each of the contained interfaces (for example, "SetContainer()") and call this method upon instantiation of the contained objects. I'd not suggest using a global member (or even CComModule-Member), because in case of an non-singleton object you'll run into big trouble.
0
 
LVL 3

Expert Comment

by:elcapitan
ID: 6997514
try this:

//create CComPtr object
CComPtr<IObj2> pobj2;

//create instance
HRESULT hr=pobj2.CoCreateInstance(__uuidof(Obj2));hr=

//call methods of your object
pobj2->whatever(/*params*/);

--EC--
0
 
LVL 3

Expert Comment

by:elcapitan
ID: 6997517
Sorry, I made a mistake. now it's fine:

//create CComPtr object
CComPtr<IObj2> pobj2;

//create instance
HRESULT hr=pobj2.CoCreateInstance(__uuidof(Obj2));

//call methods of your object
hr=pobj2->whatever(/*params*/);

--EC--
0
 

Author Comment

by:johndixson
ID: 6997614
--EC--

This creates a new instance of the component, I need to use the "outer" objects instance of the component.
0
 
LVL 22

Expert Comment

by:ambience
ID: 6998083
>> CComQIPtr<IObj2, &IID_IObj2> pobj2 (GetControllingUnknown());
The above code fails because GetControllingUnknown() returns Obj1's OWN IUnknown pointer.
So I tried the following
CComQIPtr<IObj2, &IID_IObj2> pobj2 (m_pOuterUnknown);

This all suggests that you are not creating the objects as aggregates also pointed out by snoegler.

Now here is the conceptual fight, IUnknown of the contaier is only logical to an aggregate and for an object that is not created as aggregate or which doesnot support aggregation pointer to parent is meaning less.


can post the code where you are creating the contained objects ?, do the objects support aggrgation ?

CComAggObject <CObj1> *pObj = CComAggObject <CObj1>::CreateInstance(....);

0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

Author Comment

by:johndixson
ID: 6998915
Ambience,

Here is the where the contained objects are being created. The objects formally know as OBj1 (Now cambackground) and Obj2 (now camteperature);

[ccode]
     HRESULT FinalConstruct()
     {
          // create contained components
          HRESULT     hr;
               hr = CoCreateInstance(CLSID_CamBackground, 0,
                    CLSCTX_INPROC_SERVER, IID_ICamBackground, (void**)&m_pCamBackground);


          // set temperature
          if (SUCCEEDED(hr))
               hr = CoCreateInstance(CLSID_CamSetTemp, 0, CLSCTX_INPROC_SERVER,
                    IID_ICamSetTemp, (void**)&m_pCamSetTemp);
return hr;
}

private:
IUnknown* m_pCamBackground;
IUnknown* m_pCamSetTemp;
[/ccode]

The objects do infact support aggregration, but they cannot be aggregrates.

It is my understanding that delegation is a constrained form of containment where an interface on the outer object is implemented by calls to the methods of the identical interface on the inner object. The delegated call to the method on the inner object may be preceeded and followed by other code implemented by the outer object.

This is in fact exactly what I need to perform. The inner objects are used to verify and configure hardware settings but the actual call to apply these settings is specific to the hardware in use.

Take for instance the background object above. It has a method called NeedNewDark(). This method needs to ask the temperature object what the current temperature of the CCD camera is. If the camera temperature has changed by more the a specified amount that is configured in the background object a new "background" acquisition needs to be performed.
0
 

Author Comment

by:johndixson
ID: 6998924
Ambience,

Here is the where the contained objects are being created. The objects formally know as OBj1 (Now cambackground) and Obj2 (now camteperature);


...
...
     HRESULT FinalConstruct()
     {
          // create contained components
          HRESULT     hr;
               hr = CoCreateInstance(CLSID_CamBackground, 0,
                    CLSCTX_INPROC_SERVER, IID_ICamBackground, (void**)&m_pCamBackground);


          // set temperature
          if (SUCCEEDED(hr))
               hr = CoCreateInstance(CLSID_CamSetTemp, 0, CLSCTX_INPROC_SERVER,
                    IID_ICamSetTemp, (void**)&m_pCamSetTemp);
return hr;
}

private:
IUnknown* m_pCamBackground;
IUnknown* m_pCamSetTemp;

...
...

The objects do infact support aggregration, but they cannot be aggregrates.

It is my understanding that delegation is a constrained form of containment where an interface on the outer object is implemented by calls to the methods of the identical interface on the inner object. The delegated call to the method on the inner object may be preceeded and followed by other code implemented by the outer object.

This is in fact exactly what I need to perform. The inner objects are used to verify and configure hardware settings but the actual call to apply these settings is specific to the hardware in use.

Take for instance the background object above. It has a method called NeedNewDark(). This method needs to ask the temperature object what the current temperature of the CCD camera is. If the camera temperature has changed by more the a specified amount that is configured in the background object a new "background" acquisition needs to be performed.
0
 

Author Comment

by:johndixson
ID: 6998927
Ambience,

Here is the where the contained objects are being created. The objects formally know as OBj1 (Now cambackground) and Obj2 (now camteperature);


...
...
     HRESULT FinalConstruct()
     {
          // create contained components
          HRESULT     hr;
               hr = CoCreateInstance(CLSID_CamBackground, 0,
                    CLSCTX_INPROC_SERVER, IID_ICamBackground, (void**)&m_pCamBackground);


          // set temperature
          if (SUCCEEDED(hr))
               hr = CoCreateInstance(CLSID_CamSetTemp, 0, CLSCTX_INPROC_SERVER,
                    IID_ICamSetTemp, (void**)&m_pCamSetTemp);
return hr;
}

private:
IUnknown* m_pCamBackground;
IUnknown* m_pCamSetTemp;

...
...

The objects do infact support aggregration, but they cannot be aggregrates.

It is my understanding that delegation is a constrained form of containment where an interface on the outer object is implemented by calls to the methods of the identical interface on the inner object. The delegated call to the method on the inner object may be preceeded and followed by other code implemented by the outer object.

This is in fact exactly what I need to perform. The inner objects are used to verify and configure hardware settings but the actual call to apply these settings is specific to the hardware in use.

Take for instance the background object above. It has a method called NeedNewDark(). This method needs to ask the temperature object what the current temperature of the CCD camera is. If the camera temperature has changed by more the a specified amount that is configured in the background object a new "background" acquisition needs to be performed.
0
 

Author Comment

by:johndixson
ID: 6998929
Sorry about the triple post, I am used to posting and having a "preview".
0
 
LVL 22

Accepted Solution

by:
ambience earned 500 total points
ID: 7000422
>> The objects do infact support aggregration, but they cannot be aggregrates

Why not ?

>> CoCreateInstance(CLSID_CamBackground, 0,
                   CLSCTX_INPROC_SERVER, IID_ICamBackground, (void**)&m_pCamBackground);

The second parameter is 0 so no aggregation therefore no way to Query for outer unknown, as there is none (from contained objects point of view).

You need to aggregate them, for e.g. if all the objects are in the same project you may do something like

CComAggObject< CCamBackground >* pObj1;
pObj1 = CComAggObject< CCamBackground >::CreateInstance( outerUnknown ,..);

If you are not willing to aggregate them, then the one way is as mentioned by snoegler to add a method like SetContainer or SetOuterUnknown.

Or perhaps you can add a method like SetTemparatureObj() and pass the IUnknown of temparature object, this lets you call the object directly without involving the container.

Third way depends on whether your CamBackground and CamTemparature objects can be singletons or not, if they are singletons then there is no need for any intermediate unknown, whenever you need a CamBackground just CreataInstance one, since it is a singleton you'll always have only one instance running and Creating will only return a pointer to existing instance.

for that you can add DECLARE_CLASSFACTORY_SINGLETON(..) to your objects.

Hope this helps
0
 

Author Comment

by:johndixson
ID: 7001390
Ambience,

I am glad that you pointed out the DECLARE_CLASSFACTORY_SINGLETON(..) template to my because in fact there can only be one instance of this control running at any one time.

I do beleive this will solve my problem and I'll let you know at a later date.

Thanks,

John
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now