Вопрос по c#, c++ – Как я могу передать данные MemoryStream в неуправляемую C ++ DLL с помощью P / Invoke

9

Мне нужна ваша помощь по следующему сценарию:

Я читаю некоторые данные с аппаратного обеспечения в MemoryStream (C #), и мне нужно передать эти данные в памяти в DLL, реализованную в неуправляемом C ++ (используя указатель ??). Считываемые данные (в поток) очень большие (мегабайты). Я понимаю, что я могу P / Invoke этой DLL, но я не уверен, как передать указатель / ссылку на данные потока в API C ++?

Я должен признать, что я сбит с толку, поскольку я новичок в C # - мне нужно использовать небезопасные / фиксированные, поскольку данные большие или они не имеют значения, так как объект MemoryStream управляется GC? Некоторый пример кода / подробное описание было бы очень полезно. Спасибо

Подпись неуправляемого API:

BOOL doSomething (void * rawData, int dataLength)

Требуются необработанные данные - byte / void *. Я могу изменить API DLL по мере необходимости. curious1
Какой тип данных требуется для C ++ dll? scottm

Ваш Ответ

1   ответ
13

Если он просто ожидает байты, вы можете прочитать MemoryStream в байтовый массив и затем передать указатель на это методу.

Вы должны объявить внешний метод:

[DllImport("mylibrary.dll", CharSet = CharSet.Auto)]
public static extern bool doSomething(IntPtr rawData, int dataLength);

Затем прочитайте байты из MemoryStream в байтовый массив. ВыделитьGCHandle который:

Once allocated, you can use a GCHandle to prevent the managed object from being collected by the garbage collector when an unmanaged client holds the only reference. Without such a handle, the object can be collected by the garbage collector before completing its work on behalf of the unmanaged client.

И наконец, используйте метод AddrOfPinnedObject, чтобы получить IntPtr для передачи в C ++ dll.

private void CallTheMethod(MemoryStream memStream)
{
   byte[] rawData = new byte[memStream.Length];
   memStream.Read(rawData, 0, memStream.Length);

   GCHandle rawDataHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
   IntPtr address = handle.AddrOfPinnedObject ();

   doSomething(address, rawData.Length);
   rawDataHandle.Free();
 }
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededMemoryStreamError: User Rate Limit ExceededMemoryStreamError: User Rate Limit Exceededbyte[]Error: User Rate Limit Exceededbyte[]Error: User Rate Limit ExceededMemoryStream.GetBuffer()Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы