111,098
社区成员




struct CRoomData
{
char Name[255];
double Area;
};
struct CSystemData
{
int Count;
CRoomData *RoomDatas;
};
extern "C" bool EXPORT TestF(
CSystemData *pSysData,
int SysCount
)
[StructLayout(LayoutKind.Sequential)]
public struct CRoomData
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
public byte []Name;
[MarshalAs(UnmanagedType.R8)]
public double Area;
}
[StructLayout(LayoutKind.Sequential)]
public struct CSystemData
{
[MarshalAs(UnmanagedType.I4)]
public int Count;
public IntPtr RoomDatas;
}
[DllImport("MyDll.dll", CharSet = CharSet.Ansi)]
public static extern bool TestF(
[MarshalAs(UnmanagedType.LPArray)]CSystemData[] pSysDatas,
int SysCount
);
public static void Copy(String pStr,byte []bufs)
{
byte[] tDatas = System.Text.Encoding.Default.GetBytes(pStr);
for (int k = 0; k < tDatas.Length&&k<bufs.Length; ++k)
bufs[k] = (byte)tDatas[k];
bufs[tDatas.Length] = (byte)0;
}
private void button7_Click(object sender, EventArgs e)
{
CSystemData[] tSys = new CSystemData[2];
for (int k = 0; k < 2; ++k)
{
tSys[k] = new CSystemData();
tSys[k].Count = 3;
CRoomData []tRoomDatas = new CRoomData[3];
for (int l = 0; l < 3; ++l)
{
tRoomDatas[l] = new CRoomData();
tRoomDatas[l].Area = 20 * l;
tRoomDatas[l].Name = new byte[255];
Copy(String.Format("房间{0}", l), tRoomDatas[l].Name);
}
IntPtrWrap<CRoomData> tW = new IntPtrWrap<CRoomData>();
tSys[k].RoomDatas = (IntPtr)tW.Wrap(tRoomDatas);
}
TestF(tSys, 2);
}
public class IntPtrWrap<T>
{
public System.IntPtr Ip = IntPtr.Zero;
private IntPtr[] ptArray = null;
private int arrayCount = 0;
public IntPtrWrap()
{
}
/// <summary>
/// 数组类型的初始化
/// </summary>
/// <param name="pObject"></param>
public IntPtr Wrap(T[] pObject)
{
arrayCount = pObject.Length;
//分配内存
int tSize = Marshal.SizeOf(typeof(T));
ptArray = new IntPtr[1];
ptArray[0] = Marshal.AllocHGlobal(tSize * arrayCount);
//拷贝内存
for (int k = 0; k < arrayCount; ++k)
{
IntPtr tPtr = new IntPtr(ptArray[0].ToInt64() + k * tSize);
Marshal.StructureToPtr(pObject[k], tPtr, false);
}
Ip = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * 1);
Marshal.Copy(ptArray, 0, Ip, 1);
return Ip;
}
}
public class IntPtrWrap<T> : IDisposable
{
T[] itemsReference = null;
IntPtr pointer = IntPtr.Zero;
public IntPtr Pointer
{
get
{
if (pointer == IntPtr.Zero) throw new InvalidOperationException("Pointer not initialized or destroyed");
return pointer;
}
}
public IntPtrWrap(T[] items)
{
int itemSize = Marshal.SizeOf(typeof(T));
this.pointer = Marshal.AllocHGlobal(itemSize * items.Length);
this.itemsReference = items;
for (int i = 0; i < items.Length; i++)
{
Marshal.StructureToPtr(items[i], IntPtr.Add(pointer, itemSize * i), false);
}
}
public void Dispose()
{
Marshal.FreeHGlobal(this.pointer);
this.pointer = IntPtr.Zero;
this.itemsReference = null;
}
~IntPtrWrap()
{
Dispose();
GC.SuppressFinalize(this);
}
}