-
Notifications
You must be signed in to change notification settings - Fork 508
Add simple marshaller which marshal only null COM interfaces #8128
Conversation
This idea was proposed by @MichalStrehovsky in #7994 Implemented only marshalling of `in` parameters, since this is case which I found in the stack trace of the issue. I think other directions can be implemented in same way, I just lack of examples for testing. Tested code ``` // [DllImport(Libraries.UiaCore, CharSet = CharSet.Unicode)] // public static extern IntPtr UiaReturnRawElementProvider(IntPtr hwnd, IntPtr wParam, IntPtr lParam, IRawElementProviderSimple el); IntPtr result = UiaCore.UiaReturnRawElementProvider(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null); ``` Closes #7994
ILEmitter emitter = _ilCodeStreams.Emitter; | ||
|
||
// Check if we marshall null pointer | ||
ILCodeLabel lNullInterface = emitter.NewCodeLabel(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to call a helper method to do this instead of inlining the logic here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what should I do. If you asking about labels creation, then this is how BlittableArrayMarshaller
implemented. In a sense for sure, but they are directly created there. I understand that maybe I can create helper method for reporting that scenario not supported (throwing exception code) but you point to different location. I'm lost. Can you clarify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant add a method to InteropHelpers
and just call it from here to do all the work. Many marshalers are implemented like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I properly understand you, that I add code in the System.Private.CoreLib
and then marshaller will just assume that classlib
has that method, and just call that method. Am I correctly understand you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is exactly what I meant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jkotas It's magic. Much easier then I initially thought how it should be done!
@@ -407,6 +407,26 @@ public static IntPtr GetCurrentCalleeOpenStaticDelegateFunctionPointer() | |||
return PInvokeMarshal.GetCurrentCalleeDelegate<T>(); | |||
} | |||
|
|||
public static object ConvertManagedComInterfaceToNative(object pUnk) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public static object ConvertManagedComInterfaceToNative(object pUnk) | |
public static IntPtr ConvertManagedComInterfaceToNative(object pUnk) |
The type to use for the unmanaged side should be IntPtr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(multiple places)
return null; | ||
} | ||
|
||
throw new PlatformNotSupportedException("Marhalling of non null COM interfaces does not supported"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw new PlatformNotSupportedException("Marhalling of non null COM interfaces does not supported"); | |
throw new PlatformNotSupportedException("Marhalling of non-null COM interfaces is not supported"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good modulo the type thing, thanks!
Would you mind adding a test for this under tests\src\Simple\PInvoke? There's a CPP file to put unmanaged code into, and a CS file with managed code.
@@ -68,6 +68,7 @@ public static partial class MarshalHelpers | |||
case MarshallerKind.BlittableStruct: | |||
case MarshallerKind.Decimal: | |||
case MarshallerKind.VoidReturn: | |||
case MarshallerKind.ComInterface: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be some kind of a pointer, not type
. E.g. return context.GetWellKnownType(WellKnownType.IntPtr);
(This is the native type we marshal into. Leaving this at type
would hit RyuJIT asserts added in dotnet/runtime#35026 because type
is a GC pointer. Once marshalling is done, this is an unmanaged pointer.)
return IntPtr.Zero; | ||
} | ||
|
||
throw new PlatformNotSupportedException("Marhalling of non null COM interfaces is not supported"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw new PlatformNotSupportedException("Marhalling of non null COM interfaces is not supported"); | |
throw new PlatformNotSupportedException(SR.PlatformNotSupported_ComInterop); |
@MichalStrehovsky I was little bit lazy and do not create specific functions in native code. I take existing sample which I have. Should I implement function for marshalling in native code? |
Yes please - it will be even less code that way (the interface doesn't need to have any members, etc.). I don't know what UI automation would do with this call - I don't want the test to accidentally break screen readers, so it's better to call into "known" code. |
This idea was proposed by @MichalStrehovsky in #7994
Implemented only marshalling of
in
parameters, since this is case which I found in the stack trace of the issue. I think other directions can be implemented in same way, I just lack of examples for testing.Tested code
Closes #7994