110,546
社区成员
发帖
与我相关
我的任务
分享
class Program
{
[StructLayout(LayoutKind.Sequential)]
struct MyStructA
{
public int a;
}
[StructLayout(LayoutKind.Sequential)]
struct MyStructB
{
public IntPtr pa; // *MyStructA
public IntPtr pd; // *double
public void Create(MyStructA[] As, double[] Ds)
{
int sizeAs = Marshal.SizeOf(typeof(MyStructA)) * As.Length;
//
// 系列化成byte数组 (可以直接拿AddrOfPinnedObject的指针, 不过那个GCHandle将来还是要释放的,
// 从隐藏的角度, 先拷成byte[], 而byte[]可以直接被Marshal.Copy封送)
//
byte[] tmp = new byte[sizeAs];
GCHandle gch = GCHandle.Alloc(As, GCHandleType.Pinned);
Marshal.Copy(gch.AddrOfPinnedObject(), tmp, 0, sizeAs);
gch.Free();
//
// 封送到非托管内存
//
pa = Marshal.AllocHGlobal(sizeAs);
Marshal.Copy(tmp, 0, pa, sizeAs);
pd = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)) * Ds.Length);
Marshal.Copy(Ds, 0, pd, Ds.Length);
}
public void Release()
{
Marshal.FreeHGlobal(pa);
Marshal.FreeHGlobal(pd);
pa = pd = IntPtr.Zero;
}
};
[DllImport("testdll.dll")]
static extern double testFunc(IntPtr pMyStructB);
static void Main(string[] args)
{
MyStructA[] a = new MyStructA[2] ;
a[0].a = 11; a[1].a = 22;
MyStructB[] structBs = new MyStructB[2];
structBs[0].Create(a, new double[] { 444, 555 });
structBs[1].Create(a, new double[] { 666, 777 });
GCHandle gch = GCHandle.Alloc(structBs, GCHandleType.Pinned); //
Console.WriteLine(testFunc( gch.AddrOfPinnedObject() )); // 输出 799
gch.Free(); //
structBs[0].Release();
structBs[1].Release();
Console.Read();
}
}
class MyClassB : IDisposable
{
MyStructA[] structAs;
double[] doubles;
MyStructB b;
public MyStructB Marshal()
{
/*marshal class members into unmanaged memory*/
return b;
}
public void UnMarshal()
{
/*marshal unmanaged memory into class members*/
}
public void Dispose()
{
/* free allocated unmanaged memory */
}
}