【问题标题】:How to allocate memory for an array of structure in C#如何在 C# 中为结构数组分配内存
【发布时间】:2015-06-02 09:19:03
【问题描述】:

结构 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# 中填充结构数组。

以下代码是我试图弄清楚的......

元帅密码:

面临“定义扩展非泛型静态类”的错误

 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

【问题讨论】:

  • 那么请贴出您在尝试实施该解决方案时编写的代码,并描述发生了什么,以便我们帮助您找出它不起作用的原因。
  • @phoog :我不明白如何编组这些结构,当我发布之前的链接代码时,我得到了一个扩展方法错误。我无法使类成为静态,因为它会影响其他功能已创建
  • 还有其他方式来分配结构吗??? @phoog
  • 编译错误是由于您的扩展方法在非静态或泛型类中引起的。要么将它们移到非泛型静态类中,要么使它们成为常规静态方法,或者,如果合适,实例方法。
  • 移动哪一个???@phoog

标签: c# arrays struct structure


【解决方案1】:

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

【讨论】:

  • 那么这是简单的结构,对于结构数组呢?至少对于第三个结构 ....@Olaru Mircea
  • 确实我的例子没有执行,但这里有一个答案:social.msdn.microsoft.com/Forums/vstudio/en-US/…
  • 只有我在女巫 MessageWrapper 中的一个类。
猜你喜欢
  • 2020-02-03
  • 2022-01-04
  • 1970-01-01
  • 1970-01-01
  • 2014-04-21
  • 2018-02-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多