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#中如何为结构数组分配内存

这是我在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);