在c#中处理c++结构

本文关键字:c++ 结构 处理 | 更新日期: 2023-09-27 17:53:04

我有一个关于在c#中处理c++结构体的问题。

我有一个c++结构体,来自第三方,如:

typedef struct 
{
//For application usage, will not access by the core
void* file;         //Application
void* lock;         //Application
void* appParam1;    //Application, maybe filename
unsigned int appParam2;     //Application, maybe length
void* appParam3;    //Application, maybe folder
//Will be used by the core and the hosting application
unsigned char streamMode;       //Read, Write or Append
unsigned int fileOffset;        //Actual file offset
unsigned char buf[DC_STREAM_BUF_SIZE];      //Buffer for reading and writing data
unsigned short bufSize;     //Buffer size, how much is filled from the buffer
unsigned short  bufOffset;      //Offset in reading and writing in the buffer
unsigned char queryData;        //Indicator if actual data are queried
//For internal use only, do not touch
unsigned char requestType;
signed int deviceId;
signed int param1;
unsigned short crc;
void* callback;
unsigned char objType;
void* obj;
} STREAM_HANDLE;

在c#中,这个结构体定义为:

[StructLayoutAttribute(LayoutKind.Sequential), Serializable]
public class STREAM_HANDLE
{
    public IntPtr file;         
    public object lockobj;      
    public IntPtr appParam1;
    [MarshalAsAttribute(UnmanagedType.U4)] public uint appParam2;
    public IntPtr appParam3;
    [MarshalAsAttribute(UnmanagedType.U1)]public byte streamMode;
    [MarshalAsAttribute(UnmanagedType.U4)]public uint fileOffset;       
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 0x0FFF)]public byte[] buf;
    [MarshalAsAttribute(UnmanagedType.U2)]public ushort bufSize;
    [MarshalAsAttribute(UnmanagedType.U2)]public ushort bufOffset;  
    [MarshalAsAttribute(UnmanagedType.U1)]public byte queryData;
    //For internal use only, do not touch
    [MarshalAsAttribute(UnmanagedType.U1)]public byte requestType;
    [MarshalAsAttribute(UnmanagedType.I4)]public int deviceId;
    [MarshalAsAttribute(UnmanagedType.I4)]public int param1;
    [MarshalAsAttribute(UnmanagedType.U2)]public ushort crc;
    public IntPtr callback;
    [MarshalAsAttribute(UnmanagedType.U1)]public byte objType;
    public IntPtr obj;
}

我在c#中也有一个IntPtr指向这个结构体,这样我就可以用这个指针调用c++函数。

现在的问题是,我想从c#中填充数组"但是",以便c++函数可以读取它。

下面是我用来在c#中创建句柄的代码

STREAM_HANDLE Handle = new STREAM_HANDLE
    {
        file = Marshal.StringToHGlobalAnsi(name),
        appParam1 = Marshal.StringToHGlobalAnsi(name),
        buf = new byte[0x0FFF],
        lockobj = new object(),
    };
 IntPtr HandlePointer = Marshal.AllocHGlobal(Marshal.SizeOf(Handle));
 Marshal.StructureToPtr(Handle, HandlePointer, true);

我必须用HandlePointer调用一些c++函数,我必须修改c#中"但是"的内容。

在c#中处理c++结构

MarshalAs属性将只确保buf字段在分配Marshal.AllocHGlobal时将被封送到内联数组。该结构体的c#表示有一个常规的。net数组引用作为字段。你必须像往常一样分配和初始化它。如果你想以你想要的方式使用它,你必须在c#表示和非托管句柄之间来回切换。

另一种方法是将其声明为fixed数组。这只能在unsafe上下文中实现:

unsafe struct InplaceArrayUnsafe
{
    public fixed byte Buf[10];
}
unsafe
{
    InplaceArrayUnsafe a;
    Console.WriteLine(a.Buf[4]);
    Debug.Assert(sizeof(a)); // can even do this
    UnmanagedFunction(&a); // and this
}