Получение байтового массива из вне процесса C ++ COM в C # - PullRequest
2 голосов
/ 13 ноября 2009

Какой лучший способ получить кусок памяти (т.е. void *) с COM-сервера на C #?

Мы использовали IStream (используя CreateStreamOnHGlobal) и передавали его обратно, что сработало. Однако, когда мы попробовали это на x64 CLR с x32 C ++ COM, он взорвался.

COM должен быть x32, потому что он использует внешние 32-битные DLL. C # может быть принудительно запущен 32-разрядным, но задача состоит в том, чтобы сохранить его как x64.

Ответы [ 2 ]

1 голос
/ 14 ноября 2009

Отвечая на мой вопрос.

Когда вы возвращаете IStream со своего собственного COM-сервера, DLL-библиотека взаимодействия .NET помещает IStream в его интерфейс. Например, допустим, что библиотекой типов является MyComServer, тогда взаимодействие будет содержать класс MyComServer.Interop.IStream.

этот класс IStream имеет такие функции, как RemoteRead, RemoteWrite и т. Д. В качестве первого параметра они принимают реф байт. Их использование отлично работало на 32-битных и 32-битных системах, но этот ref, вероятно, становится указателем, и поэтому на 64-битных или 32-х битах что-то пошло не так.

Решение состоит в том, чтобы преобразовать MyComServer.Interop.IStream в System.Runtime.InteropServices.ComTypes.IStream, используя «as» (или просто приведение, вероятно). Это тогда берет более знакомый byte [], int count и IntPtr для возвращаемого размера.

IntPtr раздражает, так как это может быть out int, но я использовал (набирал это вручную, чтобы не проверял компилятор ..)

byte[] buffer = new byte[100];
IntPtr ptr = Marshall.AllocHGlobal( sizeof(int) );
stream.Read( buffer, 100, ptr );
0 голосов
/ 14 ноября 2009

Если у вас есть .NET 3.5, взгляните на System.IO.Pipes - создайте хорошо известное имя канала и избавьтесь от него из неуправляемого кода с помощью API именованных каналов Win32 .

...