11

I'm calling a method via interop that returns an out IntPtr parameter. How can I get a byte* for this IntPtr so I can operate on it? I tried the following:

fixed(byte* ptr = (byte)myIntPtr)

but it didn't work. Any help would be appreciated!

Dmitri Nesteruk
  • 23,067
  • 22
  • 97
  • 166

5 Answers5

20

You can simply write:

byte* ptr = (byte*)int_ptr;

You don't have to use the fixed keyword. You don't want to pin the IntPtr, do you?

Jb Evain
  • 17,319
  • 2
  • 67
  • 67
  • This also works fine, though personally I like the ToPointer method, especially if you don't need immediately to convert it to a specific type pointer (e.g. from void* to byte*). – Noldorin Apr 03 '09 at 10:14
8

myIntPtr.ToPointer()

Noldorin
  • 144,213
  • 56
  • 264
  • 302
  • 1
    Note that the fixed keyword isn't really appropiate in this case as it is used to prevent relocation of variables. Since IntPtr is already a (managed) pointer, you essentially just want a direct conversion between the two types. See also http://msdn.microsoft.com/en-us/library/f58wzh21(VS.71).aspx – Noldorin Apr 03 '09 at 10:11
  • 3
    IntPtr in this case is *not* a managed pointer, rather an unmanaged pointer! – Anton Tykhyy Apr 03 '09 at 10:14
  • 1
    Yeah, what I really meant is that IntPtr is a managed pointer in the sense that it's part of the managed libraries, whereas byte* is an unsafe C-style pointer. Perhaps "safe" would be a better word, though it's important to note the difference between IntPtr and SafeHandle. – Noldorin Apr 03 '09 at 10:17
  • IntPtr isn't very safe either, seeing as you can cast it from/to integers. Anyway there are lots and lots of legacy APIs to work with, so IntPtr isn't going away anytime soon. – Anton Tykhyy Apr 03 '09 at 14:36
  • Well yes, it's quite fundamental to Win32 interop programming. I think I made the point the IntPtr isn't very safe (depending on which sense of the word you use) - but at least it does not require an unsafe context as pointers do. – Noldorin Apr 03 '09 at 15:53
3

I didn't want "unsafe code" in my application, so I did the following to convert an IntPtr to a byte[]. Given an IntPtr called "unsafeDataBlock":

var byteArray = new byte[dataBlockSize];
System.Runtime.InteropServices.Marshal.Copy(unsafeDataBlock, byteArray, 0, dataBlockSize);
Dimitri C.
  • 21,861
  • 21
  • 85
  • 101
2

This seemed to work for me, I wasn't using Interop but was still calling a managed C++ function from C Sharp. The managed C++ function however called unmanaged code so it accomplished the same thing as Interop.

Anyway, in the C++ function that was called from c-sharp, I used this code:

(anyPointerType*) pointer = (anyPointertype*) myIntPtr.ToPointer();
Martin Valgur
  • 5,793
  • 1
  • 33
  • 45
JD.
  • 21
  • 1
  • 1
    Just to clarify what I meant by: " I wasn't using Interop but was still calling a managed C++ function from C Sharp. The managed C++ function however called unmanaged code so it accomplished the same thing as Interop. " calling unmanged code through Interop: C-Sharp -(Using Interop calls)> unmanaged code has the same result as calling from c-sharp a managed c++ function that calls unmanaged code: C-Sharp -(Calls)> Managed C++ function -(Calls)> unmanaged code and the latter procedure is usually much easier – JD. Nov 24 '09 at 03:08
1

If you don't want unsafe code in your application, you'll have to use the methods in System.Runtime.InteropServices.Marshal, or (even better) declare your interop functions' parameter types so the marshaling happens automatically.

Anton Tykhyy
  • 19,370
  • 5
  • 54
  • 56