c#中如何为结构数组分配内存
本文关键字:数组 分配 内存 结构 | 更新日期: 2023-09-27 17:52:42
结构1:
typedef struct _wfs_cdm_cu_info
{
USHORT usTellerID;
USHORT usCount;
LPWFSCDMCASHUNIT * lppList;
} WFSCDMCUINFO, * LPWFSCDMCUINFO;
结构2:
typedef struct _wfs_cdm_cashunit
{
USHORT usNumber;
USHORT usType;
LPSTR lpszCashUnitName;
CHAR cUnitID[5];
CHAR cCurrencyID[3];
ULONG ulValues;
ULONG ulInitialCount;
ULONG ulCount;
ULONG ulRejectCount;
ULONG ulMinimum;
ULONG ulMaximum;
BOOL bAppLock;
USHORT usStatus;
USHORT usNumPhysicalCUs;
LPWFSCDMPHCU * lppPhysical;
} WFSCDMCASHUNIT, * LPWFSCDMCASHUNIT;
结构3:
typedef struct _wfs_cdm_physicalcu
{
LPSTR lpPhysicalPositionName;
CHAR cUnitID[5];
ULONG ulInitialCount;
ULONG ulCount;
ULONG ulRejectCount;
ULONG ulMaximum;
USHORT usPStatus;
BOOL bHardwareSensor;
} WFSCDMPHCU, * LPWFSCDMPHCU;
c#结构:-
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Ansi, Pack = 1)]
public struct WFSCDMPHCU { [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public string lpPhysicalPositionName;[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=5)]
public string cUnitID;
public uint ulInitialCount;
public uint ulCount;
public uint ulRejectCount;
public uint ulMaximum;
public ushort usPStatus;
public int bHardwareSensor;
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Ansi, Pack = 1)]
public struct WFSCDMCASHUNIT {
public ushort usNumber;
public ushort usType; [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public string lpszCashUnitName;[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=5)]
public string cUnitID; [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=3)]
public string cCurrencyID;
public uint ulValues;
public uint ulInitialCount;
public uint ulCount;
public uint ulRejectCount;
public uint ulMinimum;
public uint ulMaximum;
public int bAppLock;
public ushort usStatus;
public ushort usNumPhysicalCUs;
public System.IntPtr lppPhysical;
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1)]
public struct WFSCDMCUINFO {
public ushort usTellerID;
public ushort usCount;
public System.IntPtr lppList;
}
DLLImport
[DllImport(@"Dispenser.dll")]
public static extern int CDM_SetCashUnit(out WFSCDMCUINFO cuinfo);
1)我的主要问题是我应该如何marshall或分配内存为这个结构发送数据从c#到c++,第二个和第三个结构是数组的结构?
2)如果我使用指针,效率会有多高
3)如果使用c++/CLI包装器,那么我如何通过c#访问它。
我已经工作了很长时间了,我还没有弄清楚我应该如何填充c#中的结构数组。
下面的代码是我想弄清楚的…
元帅代码:
遇到"定义一个扩展非泛型静态类"的错误
public static IntPtr GetIntPtr(this object obj) {
try {
var handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
var thread = new Thread(() => {
Thread.Sleep(20000);
handle.Free();
});
thread.Start();
return handle.AddrOfPinnedObject();
} catch (ArgumentException) {
var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
Marshal.StructureToPtr(obj, ptr, false);
return ptr;
}
}
public static T FromIntPtr<T>(this IntPtr ptr) {
if (ptr == IntPtr.Zero)
return default(T);
return (T) Marshal.PtrToStructure(ptr, typeof (T));
}
c++代码的链接,我是如何调用这个函数的。link
这是我在c#中的结构映射:
[StructLayout(LayoutKind.Sequential)]
public struct Message
{
public uint MsgId;
public uint DLC;
public uint Interval;
public uint Handle;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] Data;
};
c++ here:
struct Message {
unsigned int MsgId;
unsigned int DLC;
unsigned int Interval;
unsigned int Handle;
unsigned char Data[64];
};
我在c++中的方法,它需要这样一个结构作为参数:
extern "C" __declspec(dllexport) int _stdcall MessageWrapper( Message *msg)
下面是我如何从c#中调用这个方法:
Message frame = new Message();
frame.MsgId = (uint)MsgId;
frame.DLC = (uint)Dlc;
frame.Interval = (uint)Interval;
frame.Data = new byte[64];
int rawsize = Marshal.SizeOf(frame);
IntPtr frameBuffer = Marshal.AllocHGlobal(rawsize);
Marshal.StructureToPtr(frame, frameBuffer, false);
在这里调用方法:
int response = HwWrapper.MessageWrapper(frameBuffer);
你可以在c++中做一些修改,你可以在c#中看到它们:
frame = (Message)(Marshal.PtrToStructure(frameBuffer, typeof(Message)));
Marshal.FreeHGlobal(frameBuffer);