Optional value type pointer/reference parameter during COM interop
Hey,
I am facing an interesting interop problem that I haven't found a solution for yet.
Let's say a COM method takes a pointer to a simple struct:
HRESULT Foo(LPBAR pBar);
Let's also say that this parameter is optional and the callpInterface->Foo(NULL); is perfectly valid. Now, if the structure BAR is defined in C#:
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct Bar
{
// ...
};
and the COM interop method call is also defined:
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
public void Foo(ref Bar);
In this case, there is no way to be able to call Foo(null) in C#, although it would be valid. The question is: how do I let the Marshaler know that it should pass a null value and not always expect a valid variable of type Bar? Same with Guid or other built in value types..
This is not a problem when dealing with reference types such as strings or arrays but in the case of value types?
Quick answer highly appreciated, experts! :)
[1122 byte] By [
RGabo] at [2007-12-23]
Well, Bar[] would work, but it would be more code, more memory and wouldn't even make sense as that function does not take multiple Bars but only one. IntPtr is not only more work, but it loses type information.
Any other ideas? It could easily be that there is no language construct for this. In that case, I'll just live with it.
I tend to argue with that. We are not passing a value type here but a pointer to a value type. Also, we are talking about interoperability and not value types vs reference types in general.
The current C# design does not allow you to express your intent to pass a NULL value to unmanaged code where the signature of the method requires to pass a value type by reference. I would even guess that the value type gets boxed and unboxed when passed as a reference, although I could see some JIT tricks here.
Anyways, I don't have enough time to dig deep into this issue and see if something can be done on the IL level, I am fine with this limitation.
Lucian, that makes sense too, I use Marshal.StructureToPtr and PtrToStructure when dealing with PROPVARIANTs. The problem here is that you are making the interop layer more complex. Of course, with a wrapper around it you can create a method TestPassingNull(Point? pont) and use Marhal.StructureToPtr internall or just pass IntPtr.Zero.
Can you give me the link to MSDN where you found this?