ATL COM return types in IDL 
Author Message
 ATL COM return types in IDL

Hello All.  I just started playing with ATL COM usin the wizard in Visual
Studio.  I have a C++ static library with a class that has a member function
that looks something like this:

class MyClass
{
.
.
.
.
public:
std::vector<std::string> GetListOfNames();

Quote:
};

This is currently compiled as a static library in C++.  I would like to
implement this as a COM object, and expose the public member functions of
the class in an Interface, IMyClass, or something.
I tried specifying a method in the interface definition that looked sort of
like this (don't remember exactly):

HRESULT GetListOfNames([out, retval] std::vector<std::string>);
The IDL compiler complained about the use of templates in the parameter
list.

So here's my question.  How do I go about returning a vector of strings?  Is
it possible to use user defined types as return values/parameters in ADT's
in COM interfaces?  Do I need a typedef somewhere for my template?  What
happens if I try to us this COM object in VB with a an abstract type
(assuming this is allowed)?

Thanks in advance,

Aaron



Thu, 06 Mar 2003 03:00:00 GMT  
 ATL COM return types in IDL

Greets,

    IDL is mainly 'C' like and does not support C++ constructs or types.
The proper way to wrap C++ objects in this manner is to create an interface
that will provide accessors to your vector.  Expose methods that take normal
types (or interface pointers that wrap other types).  If you want to use
type library marshalling, use automation compatible types.

    The C++ class that implements your interface can contain the vector and
internally use the various methods of the vector container that map to the
COM methods on the interface.  (i.e. your interface methods will take BSTRs
that you can use initialize a C++ string under the hood, and provide, say, a
"PushBack" method to add a string.  Below is some skeleton pseudocode for
how your IDL interface method would be defined and how you would wrap the
C++ library.

    Note, when using STL inside ATL objects, you will need to turn on
exception handling in your project's settings and take care with the use of
exceptions.  Exceptions in COM are handled through IErrorInfo facilites.
(Wrapped by AtlReportError())

-----------IDL snippet-----------
[
...
]
interface IVector : IDispatch
{
  [id(1), helpstring("Add element to vector")] HRESULT PushBack([in] BSTR
bstrItem);

Quote:
};

---In your object implementation------

class ATL_NO_VTABLE CVector:
 public IDispatchImpl<IMyObject, &IID_IMyObject, &LIBID_ATLTESTLib>
{
private:
    std::vector<std::string> m_vector;

...

// IVector
public:
 STDMETHOD(PushBack)(/*[in]*/ BSTR bstrItem);

Quote:
};

------In method implementation-------

STDMETHODIMP CVector::PushBack(BSTR bstrItem)
{
    USES_CONVERSION;

    m_vector.push_back(std::string(OLE2A(bstrItem)));

    return(S_OK);

Quote:
}

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

    Note, you can also have the CVector provide support for IEnumXXXX for
items in the vector so that you can use the For...Each statement in Visual
Basic.  If you are creating a free threaded component, be sure that you
protect access to the vector (especially if you are using iterators that can
quickly become invalidated) from concurrent access.

    If you want, you can have a COM object with a method that returns an
IVector* that can be used to represent the vector in languages such as
Visual Basic or VBScript.

Regards,

Joe



Quote:
> Hello All.  I just started playing with ATL COM usin the wizard in Visual
> Studio.  I have a C++ static library with a class that has a member
function
> that looks something like this:

> class MyClass
> {
> .
> .
> .
> .
> public:
> std::vector<std::string> GetListOfNames();
> };

> This is currently compiled as a static library in C++.  I would like to
> implement this as a COM object, and expose the public member functions of
> the class in an Interface, IMyClass, or something.
> I tried specifying a method in the interface definition that looked sort
of
> like this (don't remember exactly):

> HRESULT GetListOfNames([out, retval] std::vector<std::string>);
> The IDL compiler complained about the use of templates in the parameter
> list.

> So here's my question.  How do I go about returning a vector of strings?
Is
> it possible to use user defined types as return values/parameters in ADT's
> in COM interfaces?  Do I need a typedef somewhere for my template?  What
> happens if I try to us this COM object in VB with a an abstract type
> (assuming this is allowed)?

> Thanks in advance,

> Aaron



Thu, 06 Mar 2003 03:00:00 GMT  
 ATL COM return types in IDL

OK, I think I follow most of that.  I played around a little and made a COM
Vector object and IVector interface.  What is the syntax for having a
separate COM object return an IVector* as a parameter?  I would like to
declare both objects (the vector and the object that passes back a vector to
the client) in the same module.

In the implementation of the method that returns the IVector*, do I just
call CoCreateInstance(...) using the IVector* parameter with the [out,
retval] attributes?

Thanks,

Aaron

Quote:
> Greets,

>     IDL is mainly 'C' like and does not support C++ constructs or types.
> The proper way to wrap C++ objects in this manner is to create an
interface
> that will provide accessors to your vector.  Expose methods that take
normal
> types (or interface pointers that wrap other types).  If you want to use
> type library marshalling, use automation compatible types.

>     The C++ class that implements your interface can contain the vector
and
> internally use the various methods of the vector container that map to the
> COM methods on the interface.  (i.e. your interface methods will take
BSTRs
> that you can use initialize a C++ string under the hood, and provide, say,
a
> "PushBack" method to add a string.  Below is some skeleton pseudocode for
> how your IDL interface method would be defined and how you would wrap the
> C++ library.

>     Note, when using STL inside ATL objects, you will need to turn on
> exception handling in your project's settings and take care with the use
of
> exceptions.  Exceptions in COM are handled through IErrorInfo facilites.
> (Wrapped by AtlReportError())

> -----------IDL snippet-----------
> [
> ...
> ]
> interface IVector : IDispatch
> {
>   [id(1), helpstring("Add element to vector")] HRESULT PushBack([in] BSTR
> bstrItem);
> };

> ---In your object implementation------

> class ATL_NO_VTABLE CVector:
>  public IDispatchImpl<IMyObject, &IID_IMyObject, &LIBID_ATLTESTLib>
> {
> private:
>     std::vector<std::string> m_vector;

> ...

> // IVector
> public:
>  STDMETHOD(PushBack)(/*[in]*/ BSTR bstrItem);
> };

> ------In method implementation-------

> STDMETHODIMP CVector::PushBack(BSTR bstrItem)
> {
>     USES_CONVERSION;

>     m_vector.push_back(std::string(OLE2A(bstrItem)));

>     return(S_OK);
> }

> ------------

>     Note, you can also have the CVector provide support for IEnumXXXX for
> items in the vector so that you can use the For...Each statement in Visual
> Basic.  If you are creating a free threaded component, be sure that you
> protect access to the vector (especially if you are using iterators that
can
> quickly become invalidated) from concurrent access.

>     If you want, you can have a COM object with a method that returns an
> IVector* that can be used to represent the vector in languages such as
> Visual Basic or VBScript.

> Regards,

> Joe



> > Hello All.  I just started playing with ATL COM usin the wizard in
Visual
> > Studio.  I have a C++ static library with a class that has a member
> function
> > that looks something like this:

> > class MyClass
> > {
> > .
> > .
> > .
> > .
> > public:
> > std::vector<std::string> GetListOfNames();
> > };

> > This is currently compiled as a static library in C++.  I would like to
> > implement this as a COM object, and expose the public member functions
of
> > the class in an Interface, IMyClass, or something.
> > I tried specifying a method in the interface definition that looked sort
> of
> > like this (don't remember exactly):

> > HRESULT GetListOfNames([out, retval] std::vector<std::string>);
> > The IDL compiler complained about the use of templates in the parameter
> > list.

> > So here's my question.  How do I go about returning a vector of strings?
> Is
> > it possible to use user defined types as return values/parameters in
ADT's
> > in COM interfaces?  Do I need a typedef somewhere for my template?  What
> > happens if I try to us this COM object in VB with a an abstract type
> > (assuming this is allowed)?

> > Thanks in advance,

> > Aaron



Sat, 08 Mar 2003 03:00:00 GMT  
 ATL COM return types in IDL

HRESULT GetVector([out,retval]IVector** p);
Or
HRESULT GetVector([in] REFIID iid, [out,iid_is(iid),retval] void** p);
Now you can return the IVector back (or IVectorEx if you endup with a better
version later (if you use the latter version).
As for getting that pointer with the COM object, just use
CComObject<> :: CreateInstance();
And then QI for IVector to get that interface..

--
Girish Bharadwaj


Quote:
> OK, I think I follow most of that.  I played around a little and made a
COM
> Vector object and IVector interface.  What is the syntax for having a
> separate COM object return an IVector* as a parameter?  I would like to
> declare both objects (the vector and the object that passes back a vector
to
> the client) in the same module.

> In the implementation of the method that returns the IVector*, do I just
> call CoCreateInstance(...) using the IVector* parameter with the [out,
> retval] attributes?

> Thanks,

> Aaron


> > Greets,

> >     IDL is mainly 'C' like and does not support C++ constructs or types.
> > The proper way to wrap C++ objects in this manner is to create an
> interface
> > that will provide accessors to your vector.  Expose methods that take
> normal
> > types (or interface pointers that wrap other types).  If you want to use
> > type library marshalling, use automation compatible types.

> >     The C++ class that implements your interface can contain the vector
> and
> > internally use the various methods of the vector container that map to
the
> > COM methods on the interface.  (i.e. your interface methods will take
> BSTRs
> > that you can use initialize a C++ string under the hood, and provide,
say,
> a
> > "PushBack" method to add a string.  Below is some skeleton pseudocode
for
> > how your IDL interface method would be defined and how you would wrap
the
> > C++ library.

> >     Note, when using STL inside ATL objects, you will need to turn on
> > exception handling in your project's settings and take care with the use
> of
> > exceptions.  Exceptions in COM are handled through IErrorInfo facilites.
> > (Wrapped by AtlReportError())

> > -----------IDL snippet-----------
> > [
> > ...
> > ]
> > interface IVector : IDispatch
> > {
> >   [id(1), helpstring("Add element to vector")] HRESULT PushBack([in]
BSTR
> > bstrItem);
> > };

> > ---In your object implementation------

> > class ATL_NO_VTABLE CVector:
> >  public IDispatchImpl<IMyObject, &IID_IMyObject, &LIBID_ATLTESTLib>
> > {
> > private:
> >     std::vector<std::string> m_vector;

> > ...

> > // IVector
> > public:
> >  STDMETHOD(PushBack)(/*[in]*/ BSTR bstrItem);
> > };

> > ------In method implementation-------

> > STDMETHODIMP CVector::PushBack(BSTR bstrItem)
> > {
> >     USES_CONVERSION;

> >     m_vector.push_back(std::string(OLE2A(bstrItem)));

> >     return(S_OK);
> > }

> > ------------

> >     Note, you can also have the CVector provide support for IEnumXXXX
for
> > items in the vector so that you can use the For...Each statement in
Visual
> > Basic.  If you are creating a free threaded component, be sure that you
> > protect access to the vector (especially if you are using iterators that
> can
> > quickly become invalidated) from concurrent access.

> >     If you want, you can have a COM object with a method that returns an
> > IVector* that can be used to represent the vector in languages such as
> > Visual Basic or VBScript.

> > Regards,

> > Joe



> > > Hello All.  I just started playing with ATL COM usin the wizard in
> Visual
> > > Studio.  I have a C++ static library with a class that has a member
> > function
> > > that looks something like this:

> > > class MyClass
> > > {
> > > .
> > > .
> > > .
> > > .
> > > public:
> > > std::vector<std::string> GetListOfNames();
> > > };

> > > This is currently compiled as a static library in C++.  I would like
to
> > > implement this as a COM object, and expose the public member functions
> of
> > > the class in an Interface, IMyClass, or something.
> > > I tried specifying a method in the interface definition that looked
sort
> > of
> > > like this (don't remember exactly):

> > > HRESULT GetListOfNames([out, retval] std::vector<std::string>);
> > > The IDL compiler complained about the use of templates in the
parameter
> > > list.

> > > So here's my question.  How do I go about returning a vector of
strings?
> > Is
> > > it possible to use user defined types as return values/parameters in
> ADT's
> > > in COM interfaces?  Do I need a typedef somewhere for my template?
What
> > > happens if I try to us this COM object in VB with a an abstract type
> > > (assuming this is allowed)?

> > > Thanks in advance,

> > > Aaron



Sun, 09 Mar 2003 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Convert C++ (return type int, long, user-define, etc) function into COM/ATL

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

3. Problem with IDL for COM server returning ADO disconnected Recordset

4. Using ATL COM AppWizard on existing IDL

5. Returning different types in ATL (.NET)

6. Can COM return a struct type?

7. Can COM return a struct type?

8. Problem returning VARIANT type from a COM Interface

9. Byte Array returned from ATL COM Server to VB app

10. Returning a 64-bit value with a ATL COM

11. Returning strings from C++ (Com/ATL)

12. long data type in ATL COM VC6.0 converted to System.Int32

 

 
Powered by phpBB® Forum Software