IntPtr and Byte arrays

A

anonymous

Is there an easy way to convert a byte array into an
IntPtr? I want to P-Invoke a function that takes a
structure, which points to a byte array. I'd like to set
the structure pointer to one of my managed Byte arrays.

byte [] mybytes = new byte[400];
// fill in mybytes in managed code

public struct Mine{
int x, y;
IntPtr ByteArray;
}

//I'd like to have:
Mine mn = new Mine(); mn.ByteArray = (ref mybytes[0]);

Setting IntPtr to (Byte []) won't work since C# arrays
have a leading length count, right? Any help would be
appreciated. thanks.

(Is the only way to do a LocalAlloc for the IntPtr and
copy all the data from managed to unmanaged memory?)
 
C

Chris Tacke, eMVP

You don't want to simply pass the "address" of the array, as the memory
manager may move it and hose things. Use unsafe code to pin the array, and
that will give you a byte*, which you can then pass to your P/Invoke call.
 
A

Alex Feinman [MVP]

Most of this post was already answered. So I'll just add my 2 cents
(Is the only way to do a LocalAlloc for the IntPtr and
copy all the data from managed to unmanaged memory?)

Yes, correct. The internal layout of arrays in memory is not guaranteed to
reamin unchanged in the future builds and even service packs. While it is
possible to use GCHandle.Alloc(object, GCHandleType.Pinned) and
GCHandle.AddrOfPinnedObject, which returns the address of the array counter,
followed by the array items, it is not guaranteed to work in the future. You
should strongly consider using LocalAlloc and Marshal.Copy. There is
practically no overhead
 
G

Geoff Schwab [MSFT]

I do this for graphics routines quite often. If you are not afraid of
unsafe code then something like this will work:

unsafe
{
byte[] test = new byte[5];
fixed (byte* p = &test[0])
{
*p = 0xff;
}
}

--
Geoff Schwab
Program Manager
Excell Data Corporation
http://msdn.com/mobility
http://msdn.microsoft.com/mobility/prodtechinfo/devtools/netcf/FAQ/default.aspx

This posting is provided "AS IS" with no warranties, and confers no rights.
Chris Tacke said:
You don't want to simply pass the "address" of the array, as the memory
manager may move it and hose things. Use unsafe code to pin the array, and
that will give you a byte*, which you can then pass to your P/Invoke call.

--
Chris Tacke, eMVP
Co-Founder and Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net

anonymous said:
Is there an easy way to convert a byte array into an
IntPtr? I want to P-Invoke a function that takes a
structure, which points to a byte array. I'd like to set
the structure pointer to one of my managed Byte arrays.

byte [] mybytes = new byte[400];
// fill in mybytes in managed code

public struct Mine{
int x, y;
IntPtr ByteArray;
}

//I'd like to have:
Mine mn = new Mine(); mn.ByteArray = (ref mybytes[0]);

Setting IntPtr to (Byte []) won't work since C# arrays
have a leading length count, right? Any help would be
appreciated. thanks.

(Is the only way to do a LocalAlloc for the IntPtr and
copy all the data from managed to unmanaged memory?)
 
N

Neil Cowburn [MVP]

You can also pin objects in memory by taking advantage of the GCHandle class
found in the System.Runtime.InteropServices namespace:

using System.Runtime.InteropServices;
..
..
..
GCHandle hObject = GCHandle.Alloc(object, GCHandleType.Pinned);
IntPtr pObject = hObject.AddrOfPinnedObject();
..
..
// Write data to the allocated buffer at the pointer using Marshal.Copy()
..
if(hObject.IsAllocated)
hObject.Free();

Admittedly, this method is not as clean (in terms of code aesthetics) as
using unsafe code, and you can't write directly to a pointer as you can with
unsafe code.

--Neil

--
Neil Cowburn
Microsoft Windows Embedded MVP

This posting is provided "AS IS" with no warranties, and confers no
rights.


Chris Tacke said:
You don't want to simply pass the "address" of the array, as the memory
manager may move it and hose things. Use unsafe code to pin the array, and
that will give you a byte*, which you can then pass to your P/Invoke call.

--
Chris Tacke, eMVP
Co-Founder and Advisory Board Member
www.OpenNETCF.org
---
Windows CE Product Manager
Applied Data Systems
www.applieddata.net

anonymous said:
Is there an easy way to convert a byte array into an
IntPtr? I want to P-Invoke a function that takes a
structure, which points to a byte array. I'd like to set
the structure pointer to one of my managed Byte arrays.

byte [] mybytes = new byte[400];
// fill in mybytes in managed code

public struct Mine{
int x, y;
IntPtr ByteArray;
}

//I'd like to have:
Mine mn = new Mine(); mn.ByteArray = (ref mybytes[0]);

Setting IntPtr to (Byte []) won't work since C# arrays
have a leading length count, right? Any help would be
appreciated. thanks.

(Is the only way to do a LocalAlloc for the IntPtr and
copy all the data from managed to unmanaged memory?)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top