469,903 Members | 1,452 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,903 developers. It's quick & easy.

Three Ways to Marshal Data - Which is best?

I have operation within a class that marshals the data into a byte
array. Below are three different ways that work. Are there any
downsides to using one over the the other?

public virtual byte[] ToRaw1()
{
byte[] byteArray = new byte[Size];
IntPtr pointer = Marshal.AllocHGlobal(Size);
Marshal.StructureToPtr(this, pointer, false);
Marshal.Copy(pointer, byteArray, 0, Size);
Marshal.FreeHGlobal(pointer);
return byteArray;
}

public virtual byte[] ToRaw2()
{
byte[] byteArray = new byte[Size];
IntPtr byteArrayPtr = Marshal.UnsafeAddrOfPinnedArrayElement
(byteArray, 0);
Marshal.StructureToPtr(this, byteArrayPtr, false);
return byteArray;
}

public virtual byte[] ToRaw3()
{
byte[] byteArray = new byte[Size];
unsafe
{
fixed (byte* pData = byteArray)
{
Marshal.StructureToPtr(this, (IntPtr)pData, false);
}
}
return byteArray;
}
Nov 12 '08 #1
2 15215
Well, #2 is incorrect in that you aren't pinning the array before
passing it to UnsafeAddrOfPinnedArrayElement.

#1 is going to leak memory if an exception is thrown before the call to
FreeHGlobal.

Generally though, I would say not to use any of these. You should use
Serialization or DataContracts instead. You are marshalling in .NET, not to
unmanaged code (else, why have the byte array) and you want to go from .NET
to .NET, not from .NET to unmanaged code.

Otherwise, why have it in a byte array?

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"O.B." <fu******@bellsouth.netwrote in message
news:f3**********************************@l33g2000 pri.googlegroups.com...
>I have operation within a class that marshals the data into a byte
array. Below are three different ways that work. Are there any
downsides to using one over the the other?

public virtual byte[] ToRaw1()
{
byte[] byteArray = new byte[Size];
IntPtr pointer = Marshal.AllocHGlobal(Size);
Marshal.StructureToPtr(this, pointer, false);
Marshal.Copy(pointer, byteArray, 0, Size);
Marshal.FreeHGlobal(pointer);
return byteArray;
}

public virtual byte[] ToRaw2()
{
byte[] byteArray = new byte[Size];
IntPtr byteArrayPtr = Marshal.UnsafeAddrOfPinnedArrayElement
(byteArray, 0);
Marshal.StructureToPtr(this, byteArrayPtr, false);
return byteArray;
}

public virtual byte[] ToRaw3()
{
byte[] byteArray = new byte[Size];
unsafe
{
fixed (byte* pData = byteArray)
{
Marshal.StructureToPtr(this, (IntPtr)pData, false);
}
}
return byteArray;
}

Nov 12 '08 #2
Good call on #1. #3 is also seems to better than #1 in that it
doesn't allocate an additional buffer of memory.

I've corrected #2 as follows to pin the address first.
public virtual byte[] ToRaw2()
{
byte[] byteArray = new byte[Size];
GCHandle byteArrayPtr = GCHandle.Alloc(byteArray,
GCHandleType.Pinned);
Marshal.StructureToPtr(this, byteArrayPtr.AddrOfPinnedObject(),
false);
return byteArray;
}

However, I can't determine if #2 or #3 is better. Thoughts?

As for converting the data to a byte array, I have a structure that
serves as a generic data handler between our application and other
applications. This structure has the smarts to determine whether the
data is to be sent through an Internet socket, a COM object, or
another .NET application). To keep it generic, the interface requires
a byte array of the data being sent and received. In addition, the
data conversion to a byte array must be as fast as possible, so as to
maintain real-time operation. It has been my observation that
Marshal.StructureToPtr is faster than manually marshaling the data
into a byte array.

On Nov 12, 1:06*pm, "Nicholas Paldino [.NET/C# MVP]"
<m...@spam.guard.caspershouse.comwrote:
* * Well, #2 is incorrect in that you aren't pinning the array before
passing it to UnsafeAddrOfPinnedArrayElement.

* * #1 is going to leak memory if an exception is thrown before the call to
FreeHGlobal.

* * Generally though, I would say not to use any of these. *You should use
Serialization or DataContracts instead. *You are marshalling in .NET, not to
unmanaged code (else, why have the byte array) and you want to go from .NET
to .NET, not from .NET to unmanaged code.

* * Otherwise, why have it in a byte array?

--
* * * * * - Nicholas Paldino [.NET/C# MVP]
* * * * * - m...@spam.guard.caspershouse.com

"O.B." <funkj...@bellsouth.netwrote in message

news:f3**********************************@l33g2000 pri.googlegroups.com...
I have operation within a class that marshals the data into a byte
array. *Below are three different ways that work. *Are there any
downsides to using one over the the other?
public virtual byte[] ToRaw1()
{
*byte[] byteArray = new byte[Size];
*IntPtr pointer = Marshal.AllocHGlobal(Size);
*Marshal.StructureToPtr(this, pointer, false);
*Marshal.Copy(pointer, byteArray, 0, Size);
*Marshal.FreeHGlobal(pointer);
*return byteArray;
}
public virtual byte[] ToRaw2()
{
*byte[] byteArray = new byte[Size];
*IntPtr byteArrayPtr = Marshal.UnsafeAddrOfPinnedArrayElement
(byteArray, 0);
*Marshal.StructureToPtr(this, byteArrayPtr, false);
*return byteArray;
}
public virtual byte[] ToRaw3()
{
*byte[] byteArray = new byte[Size];
*unsafe
*{
* *fixed (byte* pData = byteArray)
* *{
* * *Marshal.StructureToPtr(this, (IntPtr)pData, false);
* *}
*}
*return byteArray;
}
Nov 12 '08 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Michael McGarry | last post: by
2 posts views Thread by Anthony Biondo Jr | last post: by
reply views Thread by jacuna | last post: by
6 posts views Thread by Immortal Nephi | last post: by
1 post views Thread by Waqarahmed | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.