Interface pointer to CComObject 
Author Message
 Interface pointer to CComObject

I have a public method as follows:

STDMETHODIMP CJobs::Add(ICJob **oJob);

I want to be able to convert the **oJob into a CComObject<CJob> so that I
can access the methods/properties I created but not exposed them to clients
via interfaces.

Is this possible?

Thanks for your help,

Neil Blackburn



Mon, 28 Feb 2005 03:06:17 GMT  
 Interface pointer to CComObject
There is no guarantee that ICJob interface you are given is really
implemented by your object. The recommended way to do what you want is
to define a separate interface that exposes the additional
functionality, and implement in on your Job object alongside ICJob. Then
CJobs can QI for this internal interface to access extra functionality.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken


Quote:
> I have a public method as follows:

> STDMETHODIMP CJobs::Add(ICJob **oJob);

> I want to be able to convert the **oJob into a CComObject<CJob> so
that I
> can access the methods/properties I created but not exposed them to
clients
> via interfaces.

> Is this possible?

> Thanks for your help,

> Neil Blackburn



Mon, 28 Feb 2005 03:15:18 GMT  
 Interface pointer to CComObject
Thanks for your help Igor.

I've implemented a private interface that seems to work fine.  To get
access to the methods/properties I'm doing the following:

STDMETHODIMP STDMETHODIMP CJobs::Add(ICJob **oJob)
{
HRESULT hRes;
long lID = 50;

CComQIPtr<ICJobPrivate, &IID_ICJobPrivate> p;

p = *oJob;

p->put_JobID(lID);

return S_OK;

Quote:
}

Is this the way you would do it yourself?

Thanks again....

Quote:

> There is no guarantee that ICJob interface you are given is really
> implemented by your object. The recommended way to do what you want is
> to define a separate interface that exposes the additional
> functionality, and implement in on your Job object alongside ICJob. Then
> CJobs can QI for this internal interface to access extra functionality.
> --
> With best wishes,
>     Igor Tandetnik

> "For every complex problem, there is a solution that is simple, neat,
> and wrong." H.L. Mencken



> > I have a public method as follows:

> > STDMETHODIMP CJobs::Add(ICJob **oJob);

> > I want to be able to convert the **oJob into a CComObject<CJob> so
>  that I
> > can access the methods/properties I created but not exposed them to
>  clients
> > via interfaces.

> > Is this possible?

> > Thanks for your help,

> > Neil Blackburn



Mon, 28 Feb 2005 18:11:59 GMT  
 Interface pointer to CComObject
Looks good, with one comment. Why are you passing a pointer to Add with
double indirection? It looks like an [in] parameter to me. If it is,
passing it as ICJob** is unnecessary and confusing - double indirection
is typically used for [out] parameters. You are making a maintenance
programmer's job harder for no apparent benefits.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken


Quote:
> Thanks for your help Igor.

> I've implemented a private interface that seems to work fine.  To get
> access to the methods/properties I'm doing the following:

> STDMETHODIMP STDMETHODIMP CJobs::Add(ICJob **oJob)
> {
> HRESULT hRes;
> long lID = 50;

> CComQIPtr<ICJobPrivate, &IID_ICJobPrivate> p;

> p = *oJob;

> p->put_JobID(lID);

> return S_OK;
> }

> Is this the way you would do it yourself?

> Thanks again....




- Show quoted text -

Quote:
> > There is no guarantee that ICJob interface you are given is really
> > implemented by your object. The recommended way to do what you want
is
> > to define a separate interface that exposes the additional
> > functionality, and implement in on your Job object alongside ICJob.
Then
> > CJobs can QI for this internal interface to access extra
functionality.
> > --
> > With best wishes,
> >     Igor Tandetnik

> > "For every complex problem, there is a solution that is simple,
neat,
> > and wrong." H.L. Mencken



> > > I have a public method as follows:

> > > STDMETHODIMP CJobs::Add(ICJob **oJob);

> > > I want to be able to convert the **oJob into a CComObject<CJob> so
> >  that I
> > > can access the methods/properties I created but not exposed them
to
> >  clients
> > > via interfaces.

> > > Is this possible?

> > > Thanks for your help,

> > > Neil Blackburn



Mon, 28 Feb 2005 21:50:14 GMT  
 Interface pointer to CComObject
A VB client is going to pass in the objects so I based the Add function on a
similar function found in a type library of a VB Active X dll.  I suppose I
forgot that the default in VB is to pass parameters ByRef so it would be
[in, out] in a VB type library.  I will attempt to change it.  Thanks for
pointing it out.

Before using the CComQIPtr I tried to use CComObject as follows:

CComObject<CJob> *p;
CComObject<CJob>::CreateInstance(&p);

// hr = p->QueryInterface(IID_ICJobPrivate, (void**) psloJob); // This did
not seem to pick up the same interface passed in
hr = p->QueryInterface(psloJob);
p->put_JobID(lID);
p->Release();

I was curious as to why this would not work.  The first QueryInterface did
not seem to get the same interface passed in.  However, with either version
I was getting an access violation in VB as the object was being deleted
after the Release().  If I took the Release() out I got an interface leak
but the setting of the ID worked fine.  I tried to AddRef() the interface
passed in, but I still received an access violation.  I would be grateful if
you could point out my mistake(s).

Thanks again.....


Quote:
> Looks good, with one comment. Why are you passing a pointer to Add with
> double indirection? It looks like an [in] parameter to me. If it is,
> passing it as ICJob** is unnecessary and confusing - double indirection
> is typically used for [out] parameters. You are making a maintenance
> programmer's job harder for no apparent benefits.
> --
> With best wishes,
>     Igor Tandetnik

> "For every complex problem, there is a solution that is simple, neat,
> and wrong." H.L. Mencken



> > Thanks for your help Igor.

> > I've implemented a private interface that seems to work fine.  To get
> > access to the methods/properties I'm doing the following:

> > STDMETHODIMP STDMETHODIMP CJobs::Add(ICJob **oJob)
> > {
> > HRESULT hRes;
> > long lID = 50;

> > CComQIPtr<ICJobPrivate, &IID_ICJobPrivate> p;

> > p = *oJob;

> > p->put_JobID(lID);

> > return S_OK;
> > }

> > Is this the way you would do it yourself?

> > Thanks again....



> > > There is no guarantee that ICJob interface you are given is really
> > > implemented by your object. The recommended way to do what you want
> is
> > > to define a separate interface that exposes the additional
> > > functionality, and implement in on your Job object alongside ICJob.
> Then
> > > CJobs can QI for this internal interface to access extra
> functionality.
> > > --
> > > With best wishes,
> > >     Igor Tandetnik

> > > "For every complex problem, there is a solution that is simple,
> neat,
> > > and wrong." H.L. Mencken



> > > > I have a public method as follows:

> > > > STDMETHODIMP CJobs::Add(ICJob **oJob);

> > > > I want to be able to convert the **oJob into a CComObject<CJob> so
> > >  that I
> > > > can access the methods/properties I created but not exposed them
> to
> > >  clients
> > > > via interfaces.

> > > > Is this possible?

> > > > Thanks for your help,

> > > > Neil Blackburn



Tue, 01 Mar 2005 04:16:03 GMT  
 Interface pointer to CComObject
How is psloJob declared?
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken


Quote:
> Before using the CComQIPtr I tried to use CComObject as follows:

> CComObject<CJob> *p;
> CComObject<CJob>::CreateInstance(&p);

> // hr = p->QueryInterface(IID_ICJobPrivate, (void**) psloJob); // This
did
> not seem to pick up the same interface passed in
> hr = p->QueryInterface(psloJob);
> p->put_JobID(lID);
> p->Release();

> I was curious as to why this would not work.  The first QueryInterface
did
> not seem to get the same interface passed in.  However, with either
version
> I was getting an access violation in VB as the object was being
deleted
> after the Release().  If I took the Release() out I got an interface
leak
> but the setting of the ID worked fine.  I tried to AddRef() the
interface
> passed in, but I still received an access violation.  I would be
grateful if
> you could point out my mistake(s).



Tue, 01 Mar 2005 06:01:53 GMT  
 Interface pointer to CComObject
First the client gets a new object through:

STDMETHODIMP CJobs::NewJob(ICJob **psloNewJob)
{
        CComPtr<ICJob> psloJob;

        CJob::CreateInstance(&psloJob);

        return psloJob.CopyTo(psloNewJob);

Quote:
}

Then they pass it to the Add function if applicable:

STDMETHODIMP CJobs::Add(ICJob **psloJob)  // Will change double indirection!

I tried to do the CComObject QueryInterface in the Add function.

Thanks....

Quote:

> How is psloJob declared?
> --
> With best wishes,
>     Igor Tandetnik

> "For every complex problem, there is a solution that is simple, neat,
> and wrong." H.L. Mencken



> > Before using the CComQIPtr I tried to use CComObject as follows:

> > CComObject<CJob> *p;
> > CComObject<CJob>::CreateInstance(&p);

> > // hr = p->QueryInterface(IID_ICJobPrivate, (void**) psloJob); // This
>  did
> > not seem to pick up the same interface passed in
> > hr = p->QueryInterface(psloJob);
> > p->put_JobID(lID);
> > p->Release();

> > I was curious as to why this would not work.  The first QueryInterface
>  did
> > not seem to get the same interface passed in.  However, with either
>  version
> > I was getting an access violation in VB as the object was being
>  deleted
> > after the Release().  If I took the Release() out I got an interface
>  leak
> > but the setting of the ID worked fine.  I tried to AddRef() the
>  interface
> > passed in, but I still received an access violation.  I would be
>  grateful if
> > you could point out my mistake(s).



Tue, 01 Mar 2005 15:19:00 GMT  
 Interface pointer to CComObject
Why did you think you could query for ICJobPrivate, store the result in
ICJob*, and get away with it? It's like casting between unrelated
classes in C++ - short trip to access violation. If you query for
ICJobPrivate, store the result in ICJobPrivate* and access it as
ICJobPrivate. If you query for ICJob, store the result as ICJob* and
access as ICJob.
--
With best wishes,
    Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken


Quote:
> First the client gets a new object through:

> STDMETHODIMP CJobs::NewJob(ICJob **psloNewJob)
> {
> CComPtr<ICJob> psloJob;

> CJob::CreateInstance(&psloJob);

> return psloJob.CopyTo(psloNewJob);
> }

> Then they pass it to the Add function if applicable:

> STDMETHODIMP CJobs::Add(ICJob **psloJob)  // Will change double
indirection!

> I tried to do the CComObject QueryInterface in the Add function.

> Thanks....




- Show quoted text -

Quote:
> > How is psloJob declared?
> > --
> > With best wishes,
> >     Igor Tandetnik

> > "For every complex problem, there is a solution that is simple,
neat,
> > and wrong." H.L. Mencken



> > > Before using the CComQIPtr I tried to use CComObject as follows:

> > > CComObject<CJob> *p;
> > > CComObject<CJob>::CreateInstance(&p);

> > > // hr = p->QueryInterface(IID_ICJobPrivate, (void**) psloJob); //
This
> >  did
> > > not seem to pick up the same interface passed in
> > > hr = p->QueryInterface(psloJob);
> > > p->put_JobID(lID);
> > > p->Release();

> > > I was curious as to why this would not work.  The first
QueryInterface
> >  did
> > > not seem to get the same interface passed in.  However, with
either
> >  version
> > > I was getting an access violation in VB as the object was being
> >  deleted
> > > after the Release().  If I took the Release() out I got an
interface
> >  leak
> > > but the setting of the ID worked fine.  I tried to AddRef() the
> >  interface
> > > passed in, but I still received an access violation.  I would be
> >  grateful if
> > > you could point out my mistake(s).



Tue, 01 Mar 2005 23:10:15 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. Reproducing CComObject<> from COM interface

2. Interface with Interface pointer from imported type library as argument

3. Communication between interfaces, CoCreateInstance and interface pointers.

4. Passing a Pointer to Pointer to an Interface

5. a pointer to the coclass from a pointer to the interface

6. Problems creating a valid object using CComObject<...>::CreateInstance

7. Using CComObject

8. make a copy for CComObject and CComVariant

9. What to use: (new CComObject) or ( pfnCreateInstance) ?

10. CComObject::Release() is being called.

11. CComObject and CComPtr

12. Error C2065 when using CComObject<xxxx>* declaration

 

 
Powered by phpBB® Forum Software