I'm not really all that well versed on unions, they more less annoy me
when i'm trying to do managed pinvoke. Whether anyone should actually do
this I'm not sure - however here's the C# code to accomplish what you were
wanting to do. The classes would remain the same in C++/CLI, you'll just
need to handle the conversion yourself. As long as the object definitions
match completely I don't see this being a problem.
This was more to satisfy my own curiosity whether it was possible or not.
Basically, I initialized a new instance of the struct and set the members
with the values I wanted in it, allocated the memory on the heap that
matched the struct size and copied the existing struct into that pointer
ensuring to destroy the old location to prevent any memory leaks.
Afterward I just marshalled the struct back to an instance of the MyObject
class. And lastly releasing the pointer created earlier for the struct.
Since Marshal.PtrToStructure creates a new copy of the object at the
pointer specified you can safely release the old pointer without having to
worry about the garbage collector releasing the new object instance.
It's important to note the StructLayout attribute decorating the MyObject
class below. Without that, the marshaller wouldn't know what to do with
the class.
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication1 {
class Program {
static void Main(string[] args) {
MyStruct struc = new MyStruct();
struc.A = 123;
struc.B = 456;
IntPtr pStruct = IntPtr.Zero;
try {
int size = Marshal.SizeOf(typeof(MyStruct));
pStruct = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(struc, pStruct, true);
MyObject obj = (MyObject)Marshal.PtrToStructure(pStruct,
typeof(MyObject));
}
finally {
if (pStruct != IntPtr.Zero) Marshal.FreeHGlobal(pStruct);
}
}
}
struct MyStruct {
public int A;
public int B;
}
[StructLayout(LayoutKind.Sequential)]
class MyObject {
int _a;
int _b;
public MyObject() {
}
public int A {
get { return this._a; }
set { this._a = value; }
}
public int B {
get { return this._b; }
set { this._b = value; }
}
}
}
ajk said:
Hi
Given an array of bytes i.e. cli::array<Byte>^ar I would like convert
from and to a structure/class
What is the best way to do this in C++/CLI ?
I have looked at using a union
class A
{ shorrt a; short b; };
union cv
{
A s;
unsigned char b[4]
}
but that isn't good way
then there is using pin_pointer
pin_pointer<Bytes> pb = &bytearray[0];
mystruct s = *reinterpret_cast<mystruct*>(pb);
but I don't want to use pin_pointers is there any better "C++/CLI"
way?
tia
Ajk