-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Closed
Labels
area-System.Runtime.InteropServicesquestionAnswer questions and provide assistance, not an issue with source code or documentation.Answer questions and provide assistance, not an issue with source code or documentation.
Description
Consider the following example where interfaces are defined in an idl file and c# declaration are created from it.
// idl file
[object, uuid(..), pointer_default(unique)]
interface IPerson : IUnknown
{
[propput] HRESULT Name([in] BSTR val);
[propget] HRESULT Name([out, retval] BSTR *pVal);
[propput] HRESULT Token([in] VARIANT val);
[propget] HRESULT Token([out, retval] VARIANT *pVal);
HRESULT GetAddress([out, retval] IAddress **ppAddress);
HRESULT GetAddressUnknown([out, retval] IUnknown **ppUnk);
};
[object, uuid(..), pointer_default(unique)]
interface IAddress : IUnknown
{
[propput] HRESULT Street([in] BSTR val);
[propget] HRESULT Street([out, retval] BSTR *pVal);
};
// cs file
[ComImport, Guid("..."), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPerson
{
string Name
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.BStr)]get;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
[param: In][param: MarshalAs(UnmanagedType.BStr)]set;
}
object Token
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Struct)]get;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
[param: In][param: MarshalAs(UnmanagedType.Struct)]set;
}
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.Interface)]
IAddress GetAddress();
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.IUnknown)]
object GetAddressUnknown();
}
[ComImport, Guid("..."), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPerson
{
string Street
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
[return: MarshalAs(UnmanagedType.BStr)]get;
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)]
[param: In][param: MarshalAs(UnmanagedType.BStr)]set;
}
}
I want to evaluate whether this example can work in .net8. The interfaces are implemented in c++ and c# and instances are passed cross-languages.
What I found out:
- there's limited COM support in .net and mainly on windows (eg functions in Marshal are windows only)
- there's a new cross platform ComWrappers mechanism (with source generators) that allows marshalling COM types from/to c# but it is IUnknown only.
- .net has the concept of marshallers eg BSTR marshaller but no Variant marshaller.
- a drop-in replacement of COM interfaces in c# where we remplace "ComImport, InterfaceType()" with the new "GeneratedComInterface" works for simple cases
but does not allow returning objects (iunknown or variant) or even returning interfaces that are also "GeneratedComInterface"
so here it does not work.
It is also a breaking change since "object" has to be changed to "IntPtr" (for iunknown)
My questions:
Are these issues known ?
Going to be fixed in future .net releases ?
Metadata
Metadata
Assignees
Labels
area-System.Runtime.InteropServicesquestionAnswer questions and provide assistance, not an issue with source code or documentation.Answer questions and provide assistance, not an issue with source code or documentation.