Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I put a void* into a COM VARIANT so that it gets marshalled as IntPtr by COM-Interop to .NET?

How do I put a void pointer (aka. void* or handle) into a COM VARIANT-Type. The wrapper class _variant_t converts it incorrectly to a boolean. But I need to put it in as pointer so that the COM-Marshaller for .NET recognizes it as IntPtr.

One of the threads I've read, was this one at MSDN Social. They suggested a solution like this:

VARIANTARG Arg; 
VariantInit(&Arg);
V_VT(&Arg) = VT_INT;
V_INT(&Arg) = (int)m_hWnd; 

The problem with this solution is, that V_INT (member intVal) is a 32 bit integer and forces the pointers to be 32 bit pointers. In other words: I can't transfer 64 bit pointers. Is there any solution for that issue? Any other way to put it in an transfer it as 64 bit integer?

I've tested this by some code. Therefore I use a .NET method that receives any System.Object and puts out its value and type.

public static void TakePtr(object ptr)
{
    Console.WriteLine("Received a " + ptr.GetType() + " with value " + ptr);
}

My VARIANT is filled for compatibility by v.llVal = 0; v.byref = myPointer; so it should get compiled always correctly regarding 32/64 bit pointers. Furthermore I need to set the variant type so that .NET mapps it to System.IntPtr without casting. (Because for the real Assembly I can't change the code and don't want to wrapp it. That would add major complexity.).

  • .NET transfers a System.IntPtr backwards as VT_INT, which forewards mapps to System.Int32.
  • VT_I8 mapps to System.Int64 but not System.IntPtr.

So what VARENUM flag would specify a System.IntPtr?

like image 580
Christoph Meißner Avatar asked Oct 17 '25 05:10

Christoph Meißner


1 Answers

That's not possible, VARIANT is an automation type. Automation does not like to deal with pointers to an unknown type, there's no safe way to dereference them. The only pointer types supported are IUnknown* and IDispatch*, interface pointers.

At best you could store it as a VT_I8 which marshals to a long. Which you can then cast to IntPtr.

like image 178
Hans Passant Avatar answered Oct 18 '25 17:10

Hans Passant



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!