I need to convert the following struct to a byte array:
[Serializable]
public struct newLeads
{
public string id;
public string first_name;
public string last_name;
}
I’m trying to convert to the byte array with the following code:
public class ConvertStruct
{
public static byte[] StructureToByteArray(object obj)
{
int Length = Marshal.SizeOf(obj);
byte[] bytearray = new byte[Length];
IntPtr ptr = Marshal.AllocHGlobal(Length);
Marshal.StructureToPtr(obj, ptr, false);
Marshal.Copy(ptr, bytearray, 0, Length);
Marshal.FreeHGlobal(ptr);
return bytearray;
}
}
I’m getting the exception on line:
IntPtr ptr = Marshal.AllocHGlobal(Length);
Exception: Attempt by security transparent method ‘Classes.ConvertStruct.ConvertStruct.StructureToByteArray(System.Object)’ to access security critical method ‘System.Runtime.InteropServices.Marshal.AllocHGlobal(Int32)’ failed.”}
My Question is? How can I fix this to avoid the exception and convert my simple struct into a byte[]?
Thanks in advance!
UPDATE: I tried this in a console application and it works. I’m calling this from an asp.net page code-behind so that must have something to do with it, but I can’t figure out what!
Set an appropiate marshaling for string (taking from the answer by goric), whithout that, what you will get is the memory address of the strings in the byte array (not a good thing).
In your comment you said that this code fails sooner. Well, it uses a Security Permission Demand (as recommended for .NET 4) at it will check for the particular permision each time the method is called. You may try to execute it without it, and the expected result is what you got at the begining.
The real answer
You must be running in a constrained enviroment, probably some kind of sandbox or a platform that doesn’t support pointers. In that case, we may need to do the convertion by other means.
You said ASP.NET? so that’s it.
In order to the convertion without pointers, try this technique:
At this point I need to know a bit more about your situation to give you a better solution, in particular who or what is going to read that byte array?. Anyway, you could encode the length of the strings, like so (reserving -1 for null):
Lastly, we need to join those arrays. I know this can be optimized much more… (A good idea for that use MemoryStream and StreamWriter) Anyway, this is my first implementation [tested]:
Note: I didn’t use null terminated strings because I don’t know what encoding you will end up using.
Optimization
Same logic, but implemented with streams (Union did not change)[tested].
Reding the strings back
To get the data back, we begin by reading the length of the string (With the same type Union):
Our next step would be to read that many characters, to do that we will use an StreamReader:
With this we build a method to decode the strings:
And finally the method to recover a newLeads (Again with the same Union type)[tested]: