CComObject

 Hi !

I receive an IDispatch* in a COM object's method. I know what object should it be.
I would like to acces it's ATL class so I can manipulate it.
Details:

class ATL_NO_VTABLE CMyObj :
   public CComObjectRootEx...
   ...

STDMETHODIMP COtherObj::Manipulate(IDispatch *ptr)
{
   CMyObj *obj=???ptr???
   obj->m_iY=1;
   obj->Manipulate(...);
}

Maybe using CComObject or something like that.

  Stewe
LVL 1
steweAsked:
Who is Participating?
 
peterchen092700Connect With a Mentor Commented:
The main point is that casting the IMyObj to a CMyObj is against the "contract" that the client agreed on when using IMyObj. It's relying on something that isn't guaranteed.

>> I could break it with one additional registry entry
This is only an illustration what could happen:

I could replace your MyObj implementation with a similar that is implemented in a completely different way - or even a completely different language.

I could force the MyObj component to always run in an surrogate process (which is a usual way to avoid one faulty component to break down the entire application).

I could force MyObj always to be created on a remote server.

All these things can be achieved without touching your binaries, just by changing some registry settings.

The problem in these cases is: your client will get a CMyObj* as well, but the pointer is utterly meaningless, accesing it most likely causes an access violation, and there's no one-step check that your CMyObj pointer is valid.

------------------

Alternatives:
I know that passing all information through a COM interface is harsh.
The only alternative would be the client (the module that *receives* the IDispatch *) to be the one that also creates the MyObj instance, and keeps both the CMyObj* and the IMyObj* around.

Peter
0
 
migelCommented:
Hi!
You can`t directly cast IDispatch pointer to the your object since you can receive anything else.
You can add internal interface (not registered in the TLB) to the your class and manupulate it by this interface
0
 
AcrklorCommented:
Hi!

(Don't really know what migel means - need not to be wrong, though -, but)
I would make it this way:

STDMETHODIMP COtherObj::Manipulate(IDispatch *ptr)
{
  IMyObj *obj;
  ptr->QueryInterface(IID_IMyObj, (void**)&obj);
  obj->m_iY=1;
  obj->Manipulate(...);
}
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

 
steweAuthor Commented:

This is the way that I'm using now.
But. m_iY is not a COM property but a C++ class property.
So I need
  class MyObj*
not
  IMyObj *
Is it possible ?
0
 
peterchen092700Commented:
>>>> So I need class MyObj*  not IMyObj * Is it possible ?

No, it's not (that's what miguel wanted to say).

The design of COM limits you to using the interface, since you don't know for sure what "hides behind" the IMyObj*. In fact, you could even get it working undercertain conditions, but I could break it with one additional registry entry.
0
 
migelCommented:
Thank you peter! my English not so guud :-)
0
 
steweAuthor Commented:
What do you mean 'I could break it with one additional registry entry' ?
0
 
migelCommented:
HI!
By this phrase, Peter mean that any user can implement your interface and pass such object to you. So unpredictable result can occure.
0
 
steweAuthor Commented:
Yea. I do it.
I keep CMyObj in-touch, f.e. mapped, and look up with a string property as key. So I use that IDispatch (IMyObj) to get the key value, then look up.

and... it works.

   Thx
0
 
peterchen092700Commented:
>> I keep CMyObj in-touch, f.e. mapped, and look up with a string property as key.
perfect!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.