如何在C#中为结构数组分配内存

时间:2015-06-02 09:19:03

标签: c# arrays struct structure

结构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)我的主要问题是如何为这个结构编组或分配内存以将数据从C#发送到C ++,第二个和第三个结构是结构数组???

2)如果我使用指针效率会如何。

3)如果使用C ++ / CLI包装器,那么我如何通过C#访问它。

我工作已经很长时间了,我还要弄清楚如何在C#中填充结构数组。

Follwing代码是我试图找出的......

元帅代码:

面对错误"定义扩展非泛型静态类"

 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

1 个答案:

答案 0 :(得分:0)

这是我在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 ++:

    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);