COM/ATL novice:passing object pointers through methods on a COM interface 
Author Message
 COM/ATL novice:passing object pointers through methods on a COM interface

Hi,
Are the parameter passing capabilities of ATL/COM limited to the data
types defined for MIDL? Is it not possible to pass pointers to objects
as method parameters back and forward across component boundries?

Lets say I define the following interfaces in an .IDL file:

            [
                        object,
                        uuid(5D220C6F-ACE7-4933-A4E3-A588C1F2904B),
                        dual,
                        helpstring("IDataObject Interface"),
                        pointer_default(unique)
            ]
            interface IDataObject : IDispatch
            {
                        ..
                        ..
            };

            [
                        object,
                        uuid(992C58D4-6188-4745-90C0-1229FD6F0999),
                        dual,
                        helpstring("IDataProccesingObj"),
                        pointer_default(unique)
            ]
            interface IDataProccesingObj : IDispatch
            {
                        [id(1), helpstring("method processDataObject")]
HRESULT method processDataObject([in, out] IDataObject **iData);
            };

Having provided implementations for the IDataObject and
IDataProccesingObj interfaces and built the .dll with the type library,
I would (naturally) create a test client for the COM objects. Since I'm
not really into the complexity of the COM architecture, I'd prefer to
just obtain access to the COM objects using smart pointers provided by
the type library. A snippet of client code could look something like
this:

..
..
#import "nameoftypeLibrary.dll" no_namespace
..
..
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
            try
            {
                        IDataObjectPtr pDataObject;
                        IDataProccesingObjPtr pDataProcessingObject;

                        HRESULT hr  =
pDataObject.CreateInstance(__uuidof(IDataObject));

                        // Do some initialization of the data object
                        ..
                        ..

                        hr =
pDataProccesingObj.CreateInstance(__uuidof(IDataProccesingObj));
                        pDataProccesingOb->method
processDataObject(&IDataObjectPtr); //..or something like that
            }
            catch(_com_error &ce)
            {
                        printf("Error:\n");
                        printf("Code = %08lx\n", ce.Error());
                        printf("Code meaning = %s\n", (char*)
ce.ErrorMessage());
                        printf("Source = %s\n", (char*) ce.Source());
                        printf("Description = %s\n", (char*)
ce.Description());
            }

Quote:
}

My question is whether such an approach is worth considering? Being a
COM novice, I accept the possibility for making some pretty far-fetched
presumtions here, but I will, however, highly appreciate some advice on
how to pass object pointers through methods on a COM interface.

Regards, Trond



Sun, 03 Jul 2005 18:12:56 GMT  
 COM/ATL novice:passing object pointers through methods on a COM interface

Quote:

>                         [id(1), helpstring("method processDataObject")]
> HRESULT method processDataObject([in, out] IDataObject **iData);
>             };

Is "method" #defined away?  I don't recognize it as an MIDL keyword,
although it might be something introduced in .Net? Otherwise, this is
OK.

Quote:
> #import "nameoftypeLibrary.dll" no_namespace
> ..
> ..
> int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
> {
>             try
>             {
>                         IDataObjectPtr pDataObject;
>                         IDataProccesingObjPtr pDataProcessingObject;

>                         HRESULT hr  =
> pDataObject.CreateInstance(__uuidof(IDataObject));

The UUID passed to CreateInstance needs to be that of a coclass, not
an interface.  Also note that you can use one of the constructor
overloads on _com_ptr_t<> to do this in one step, and without getting
an HRESULT to check, e.g.

    IDataObjectPtr pDataObject(__uuidof(DataObject));

This will throw if the CoCreateInstance call fails.

Quote:
>                         // Do some initialization of the data object
>                         ..
>                         ..

>                         hr =
> pDataProccesingObj.CreateInstance(__uuidof(IDataProccesingObj));
>                         pDataProccesingOb->method
> processDataObject(&IDataObjectPtr); //..or something like that

Again, I'm not sure about the presence of method.  You'll want to pass
pDataObject by address, rather than taking the address of IDataObjectPtr
(in fact, I don't guess what you have there would compile).  And you'll
want to be aware that _com_ptr_t<> smart pointers erase the contained
pointer when you use their address operator.  How much of a problem this
is depends on the implementation of processDataObject().  If it creates
an instance of DataObject if passed the address of a NULL pointer, then
it's not a problem (although it does make the code earlier in main()
that creates a DataObject pointless).  If not, you need to do the call
a little bit differently, e.g.

    IDataObject* pRawDataObject = pDataObject;
    pDataProcessingObj->processDataObject(&pRawDataObject);

And note that this method will cause problems of its own if
processDataObject moves its argument around.

Quote:
> My question is whether such an approach is worth considering?

Absolutely, in fact it's pretty much the right way to do it.

--
Craig Powers
MVP - Visual C++



Sun, 03 Jul 2005 22:59:17 GMT  
 COM/ATL novice:passing object pointers through methods on a COM interface
The IDataObject interface is not Automation-compatible. You can't use it
when defining dual interfaces.

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD

MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================


Quote:
> Hi,
> Are the parameter passing capabilities of ATL/COM limited to the data
> types defined for MIDL? Is it not possible to pass pointers to objects
> as method parameters back and forward across component boundries?

> Lets say I define the following interfaces in an .IDL file:

>             [
>                         object,
>                         uuid(5D220C6F-ACE7-4933-A4E3-A588C1F2904B),
>                         dual,
>                         helpstring("IDataObject Interface"),
>                         pointer_default(unique)
>             ]
>             interface IDataObject : IDispatch
>             {
>                         ..
>                         ..
>             };

>             [
>                         object,
>                         uuid(992C58D4-6188-4745-90C0-1229FD6F0999),
>                         dual,
>                         helpstring("IDataProccesingObj"),
>                         pointer_default(unique)
>             ]
>             interface IDataProccesingObj : IDispatch
>             {
>                         [id(1), helpstring("method processDataObject")]
> HRESULT method processDataObject([in, out] IDataObject **iData);
>             };

> Having provided implementations for the IDataObject and
> IDataProccesingObj interfaces and built the .dll with the type library,
> I would (naturally) create a test client for the COM objects. Since I'm
> not really into the complexity of the COM architecture, I'd prefer to
> just obtain access to the COM objects using smart pointers provided by
> the type library. A snippet of client code could look something like
> this:

> ..
> ..
> #import "nameoftypeLibrary.dll" no_namespace
> ..
> ..
> int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
> {
>             try
>             {
>                         IDataObjectPtr pDataObject;
>                         IDataProccesingObjPtr pDataProcessingObject;

>                         HRESULT hr  =
> pDataObject.CreateInstance(__uuidof(IDataObject));

>                         // Do some initialization of the data object
>                         ..
>                         ..

>                         hr =
> pDataProccesingObj.CreateInstance(__uuidof(IDataProccesingObj));
>                         pDataProccesingOb->method
> processDataObject(&IDataObjectPtr); //..or something like that
>             }
>             catch(_com_error &ce)
>             {
>                         printf("Error:\n");
>                         printf("Code = %08lx\n", ce.Error());
>                         printf("Code meaning = %s\n", (char*)
> ce.ErrorMessage());
>                         printf("Source = %s\n", (char*) ce.Source());
>                         printf("Description = %s\n", (char*)
> ce.Description());
>             }
> }

> My question is whether such an approach is worth considering? Being a
> COM novice, I accept the possibility for making some pretty far-fetched
> presumtions here, but I will, however, highly appreciate some advice on
> how to pass object pointers through methods on a COM interface.

> Regards, Trond



Mon, 04 Jul 2005 06:29:35 GMT  
 COM/ATL novice:passing object pointers through methods on a COM interface



Quote:
> Hi,
> Are the parameter passing capabilities of ATL/COM limited to the data
> types defined for MIDL? Is it not possible to pass pointers to objects
> as method parameters back and forward across component boundries?

You can pass a COM object to a COM method as an IUnknown or IDispatch. Your
method will then have to do QueryInterface to get the specific interface you
need.


Mon, 04 Jul 2005 17:50:08 GMT  
 COM/ATL novice:passing object pointers through methods on a COM interface
Thanks a lot, guys!

My implementation of  "interface-pointer-reference-parameter-passing" back
and forward through COM interface metods are running smoothly. Still being
something of a COM/ATL nivice, I'm not really sure what  Alexander Nickolov
means means when he claims that I can't use IDataObject when defining dual
interfaces. However, the impl. works great with a C++ client.

Regards, Trond


Quote:
> Hi,
> Are the parameter passing capabilities of ATL/COM limited to the data
> types defined for MIDL? Is it not possible to pass pointers to objects
> as method parameters back and forward across component boundries?

> Lets say I define the following interfaces in an .IDL file:

>             [
>                         object,
>                         uuid(5D220C6F-ACE7-4933-A4E3-A588C1F2904B),
>                         dual,
>                         helpstring("IDataObject Interface"),
>                         pointer_default(unique)
>             ]
>             interface IDataObject : IDispatch
>             {
>                         ..
>                         ..
>             };

>             [
>                         object,
>                         uuid(992C58D4-6188-4745-90C0-1229FD6F0999),
>                         dual,
>                         helpstring("IDataProccesingObj"),
>                         pointer_default(unique)
>             ]
>             interface IDataProccesingObj : IDispatch
>             {
>                         [id(1), helpstring("method processDataObject")]
> HRESULT method processDataObject([in, out] IDataObject **iData);
>             };

> Having provided implementations for the IDataObject and
> IDataProccesingObj interfaces and built the .dll with the type library,
> I would (naturally) create a test client for the COM objects. Since I'm
> not really into the complexity of the COM architecture, I'd prefer to
> just obtain access to the COM objects using smart pointers provided by
> the type library. A snippet of client code could look something like
> this:

> ..
> ..
> #import "nameoftypeLibrary.dll" no_namespace
> ..
> ..
> int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
> {
>             try
>             {
>                         IDataObjectPtr pDataObject;
>                         IDataProccesingObjPtr pDataProcessingObject;

>                         HRESULT hr  =
> pDataObject.CreateInstance(__uuidof(IDataObject));

>                         // Do some initialization of the data object
>                         ..
>                         ..

>                         hr =
> pDataProccesingObj.CreateInstance(__uuidof(IDataProccesingObj));
>                         pDataProccesingOb->method
> processDataObject(&IDataObjectPtr); //..or something like that
>             }
>             catch(_com_error &ce)
>             {
>                         printf("Error:\n");
>                         printf("Code = %08lx\n", ce.Error());
>                         printf("Code meaning = %s\n", (char*)
> ce.ErrorMessage());
>                         printf("Source = %s\n", (char*) ce.Source());
>                         printf("Description = %s\n", (char*)
> ce.Description());
>             }
> }

> My question is whether such an approach is worth considering? Being a
> COM novice, I accept the possibility for making some pretty far-fetched
> presumtions here, but I will, however, highly appreciate some advice on
> how to pass object pointers through methods on a COM interface.

> Regards, Trond



Fri, 08 Jul 2005 20:57:58 GMT  
 COM/ATL novice:passing object pointers through methods on a COM interface
IDataObject is not Automation-compatible, therefore a dual interface
cannot use it as an argument type in any of its methods' signatures.
You should be getting a warning (an error really) from MIDL that your
interface is not Automation-compatible.

--
=====================================
Alexander Nickolov
Microsoft MVP [VC], MCSD

MVP VC FAQ: http://www.mvps.org/vcfaq
=====================================


Quote:
> Thanks a lot, guys!

> My implementation of  "interface-pointer-reference-parameter-passing" back
> and forward through COM interface metods are running smoothly. Still being
> something of a COM/ATL nivice, I'm not really sure what  Alexander Nickolov
> means means when he claims that I can't use IDataObject when defining dual
> interfaces. However, the impl. works great with a C++ client.

> Regards, Trond


> > Hi,
> > Are the parameter passing capabilities of ATL/COM limited to the data
> > types defined for MIDL? Is it not possible to pass pointers to objects
> > as method parameters back and forward across component boundries?

> > Lets say I define the following interfaces in an .IDL file:

> >             [
> >                         object,
> >                         uuid(5D220C6F-ACE7-4933-A4E3-A588C1F2904B),
> >                         dual,
> >                         helpstring("IDataObject Interface"),
> >                         pointer_default(unique)
> >             ]
> >             interface IDataObject : IDispatch
> >             {
> >                         ..
> >                         ..
> >             };

> >             [
> >                         object,
> >                         uuid(992C58D4-6188-4745-90C0-1229FD6F0999),
> >                         dual,
> >                         helpstring("IDataProccesingObj"),
> >                         pointer_default(unique)
> >             ]
> >             interface IDataProccesingObj : IDispatch
> >             {
> >                         [id(1), helpstring("method processDataObject")]
> > HRESULT method processDataObject([in, out] IDataObject **iData);
> >             };

> > Having provided implementations for the IDataObject and
> > IDataProccesingObj interfaces and built the .dll with the type library,
> > I would (naturally) create a test client for the COM objects. Since I'm
> > not really into the complexity of the COM architecture, I'd prefer to
> > just obtain access to the COM objects using smart pointers provided by
> > the type library. A snippet of client code could look something like
> > this:

> > ..
> > ..
> > #import "nameoftypeLibrary.dll" no_namespace
> > ..
> > ..
> > int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
> > {
> >             try
> >             {
> >                         IDataObjectPtr pDataObject;
> >                         IDataProccesingObjPtr pDataProcessingObject;

> >                         HRESULT hr  =
> > pDataObject.CreateInstance(__uuidof(IDataObject));

> >                         // Do some initialization of the data object
> >                         ..
> >                         ..

> >                         hr =
> > pDataProccesingObj.CreateInstance(__uuidof(IDataProccesingObj));
> >                         pDataProccesingOb->method
> > processDataObject(&IDataObjectPtr); //..or something like that
> >             }
> >             catch(_com_error &ce)
> >             {
> >                         printf("Error:\n");
> >                         printf("Code = %08lx\n", ce.Error());
> >                         printf("Code meaning = %s\n", (char*)
> > ce.ErrorMessage());
> >                         printf("Source = %s\n", (char*) ce.Source());
> >                         printf("Description = %s\n", (char*)
> > ce.Description());
> >             }
> > }

> > My question is whether such an approach is worth considering? Being a
> > COM novice, I accept the possibility for making some pretty far-fetched
> > presumtions here, but I will, however, highly appreciate some advice on
> > how to pass object pointers through methods on a COM interface.

> > Regards, Trond



Sun, 10 Jul 2005 07:15:30 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. passing COM object pointers to another COM object in ATL

2. ATL COM - Passing ATL COM classes through another ATL COM class in the same app

3. Return a pointer to a nested COM object from a COM object method

4. Passing COM objects as parameters to other COM objects

5. Passing COM objects as parameters to other COM objects

6. Problem to pass COM interface to a method

7. COM Interop - How to pass C# uint array to COM interface which takes UINT *pArray

8. Howto Expose a normal C++ class with methods via an Interface Class in ATL COM

9. Newbie COM Interop: passing null ref object to a method

10. Passing an array through the COM interface in ATL

11. Getting iwebbrowser2 from ishellbrowser--the interface passed to setsite of internet explorer toolbar button com object

12. Getting iwebbrowser2 from ishellbrowser--the interface passed to setsite of internet explorer toolbar button com object

 

 
Powered by phpBB® Forum Software