Discussion:
How to treat GetEnumerator(); from C++ COM's IEnumVARIANT
(too old to reply)
Juan Dent
2004-08-18 21:45:02 UTC
Permalink
Hi,

I have an interface in C# like so:

public interface ICollectionJD
{
// support for enumeration
[DispId(-4), Description("property _NewEnum")]
IEnumerator GetEnumerator();
}

I am implementing a wrapper for this managed code in C++, where I declare
the interface like so:

__interface ICollection : IDispatch
{
[id(-4), helpstring("property _NewEnum")] HRESULT GetEnumerator([out,
retval] IEnumVARIANT** pRetVal);
}

Or like so:

__interface ICollection : IDispatch
{
[propget, id(-4), helpstring("property _NewEnum")] HRESULT _NewEnum([out,
retval] IUnknown** pVal);
}

The coclass in C++ looks like:

class ATL_NO_VTABLE CCollection :
public ICollection
{
private:
gcroot<PropertyDefaultsCollection*> managed;
public:
CCollection()
{
this->managed=new PropertyDefaultsCollection();
}
//...
}

where PropertyDefaultsCollection is a public class in C# that implements the
ICollectionJD interface.

My problem is in the implementation of GetEnumerator(), trying:

STDMETHODIMP CCollection::GetEnumerator(IEnumVARIANT** pVal)
{
IntPtr ptr = IntPtr::Zero;
try
{
IEnumerator* enumerator = managed->GetEnumerator();
ptr = Marshal::GetIUnknownForObject( enumerator );
*pVal = (IEnumVARIANT*)ptr.ToPointer();
return S_OK;
}
catch( Exception * ex)
{
return Marshal::GetHRForException( ex );
}
}


When I call this from a client in VB6, using:

dim o as object
for each o in wrap
'...
next

I get this error:

Runtime error '451':
Property let procedure not defined and property get procedure did not
return an object.


What am I doing wrong?
--
Thanks in advance,

Juan Dent, M.Sc.
Mattias Sjögren
2004-08-19 09:59:06 UTC
Permalink
Juan,
Post by Juan Dent
What am I doing wrong?
You can't cast the IUnknown pointer returned by GetIUnknownForObject()
to IEnumVARIANT* like that. If anything, you should QueryInterface()
for it. But managed enumerators don't even implement IEnumVARIANT.

Try using the
System.Runtime.InteropServices.CustomMarshalers.EnumVariantViewOfEnumerator
class in CustomMarshalers.dll instead. It provides an IEnumVARIANT
wrapper around an IEnumerator object.



Mattias
--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Peter Huang
2004-08-20 05:21:52 UTC
Permalink
Hi Juan,

As the MSDN document said:
The EnumeratorToEnumVariantMarshaler type supports the .NET Framework
infrastructure and is not intended to be used directly from your code.

Now I am searching if there is any document about the GetInstance document.
From the document about how to Implementing the ICustomMarshaler Interface,
cookie string is defined as below.

A cookie passed to the custom marshaler. You can use the cookie to provide
additional information to the marshaler. For example, the same marshaler
could be used to provide a number of wrappers, for which the cookie
identifies the specific wrapper. The cookie is passed to the GetInstance
method of the marshaler.

Since the EnumeratorToEnumVariantMarshaler is for internal used, there is
no public document for the method. But as the document said, the cookie is
usually used to identify the ICustomMarshaler.

Hope this helps.

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Peter Huang
2004-08-23 08:43:38 UTC
Permalink
Hi Juan,

So far I can not find a external document about how to use the internal
used class EnumeratorToEnumVariantMarshaler.
BTW, why not use the RegAsm tool to generate a tlb file for the managed
class directly?
If you have any concern please feel free to let me know and we will try to
give the feedback to our product team to see if we can build a document for
the EnumeratorToEnumVariantMarshaler in furture.

Thank you for your understanding!

Best regards,

Peter Huang
Microsoft Online Partner Support

Get Secure! - www.microsoft.com/security
This posting is provided "AS IS" with no warranties, and confers no rights.
Loading...