views:

792

answers:

4

I need to pass an IntPtr to IStream.Read, and the IntPtr should point to a ulong variable. How do I get this IntPtr that points to my ulong variable?

A: 
var pointer = new IntPtr(&myVariable);
mquander
While this does get the pointer, you haven't asked the GC to keep it fixed, so myVariable may be moved and that pointer no longer belongs to you.
Samuel
+2  A: 

I believe you have to use the GCHandle method if you want to avoid unsafe code. I am not sure on how this works with boxed value types.

var handle = GCHandle.Alloc(myVar, GCHandleType.Pinned);
var ptr = handle.AddrOfPinnedObject()
Simon Svensson
This approached worked. Interestingly I still needed to Marshal.WriteInt64 the value back to my ulong variable (perhapsit was just the debugged that was not smart enough though)
Ries
+1  A: 

If you cannot use unsafe code try the following.

var myValue = GetTheValue();
var ptr = Marshal.AllocHGLobal(Marshal.SizeOf(typeof(ulong));
Marshal.StructureToPointer(ptr, myValue, false);

At some point later on, you will need to call Marshal.FreeHGlobal on the "ptr" value.

JaredPar
+3  A: 

The best way is to change the IStream definition:

void Read([Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv,
          int cb, /*IntPtr*/ ref int pcbRead);

Then you can write

int pcbRead = 0;
Read(..., ref pcbRead);
Stefan Schultze
Aftre some thought I realized this was my best option. IStream is after all just an interface. Why not create my own interface...
Ries