Обрабатывать структуры C ++ в C #

У меня есть вопрос об обработке структур из 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 ++ с этим указателем. Это работает очень хорошо.

Теперь проблема в том, что я хочу заполнить массив «buf» из 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);

Я должен вызвать некоторые функции C ++ с HandlePointer, и я должен изменить содержимое «buf» в C #.

1

Решение

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
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector