Подтвердить что ты не робот

Как я могу передавать данные из управляемой сборки в родную библиотеку и обратно?

Как я могу передать данные (текст) из управляемой сборки в собственную библиотеку и передать данные (текст) обратно на управляемую сборку?

В частности, я хочу показать System.IO.Stream какой-то вид на стороне .NET и (наиболее важно) FILE * с внутренней стороны.

Подпись собственного метода должна быть:

FILE * foo(FILE * bar);

Подпись оболочки вокруг нативного вызова p/invoke должна быть:

CustomStream foo(CustomStream bar);

Я не хочу использовать методы обратного вызова на родной стороне (один для получения большего количества данных и один для установки большего количества данных). Я хочу использовать FILE * с внутренней стороны - и все связанные с ним методы, которые работают на нем, например fprintf.

Мне не нужен дисковый ввод-вывод. Это должно быть операцией с памятью.

У меня есть полный контроль над управляемой сборкой и собственной библиотекой.

Решение должно работать с .NET 2.0

Я готов создать любой управляемый или неуправляемый слой прокладки, необходимый для снятия этого.

"Очевидным" решением является использование STDIN и STDOUT и запуск дочернего процесса - однако я не хочу отдельный процесс. Кроме того, мои попытки перенаправить потоки STDIN и STDOUT из родной библиотеки, которая не является консольным приложением в Windows, потерпели неудачу несколько эффектно (и с большим ударом головой).

Исходя из этого вопроса: Перенаправить stdout + stderr в службу Windows С#. Я попытался изменить подход (по крайней мере), решить половину проблемы "ответа", но без FileStream (так как я хочу нечто более похожее на MemoryStream). Однако FileStream - единственный тип потока, который предоставляет подходящий дескриптор потока низкого уровня.

В противном случае, я довольно хорошо застрял, и в настоящее время я думаю, что мне нужно будет погрузиться глубже и придумать собственную ручную ручную реализацию, но не знаю, с чего начать.


Решение

Наконец-то!

Я разместил здесь полный образец проекта:

http://pastebin.com/jcjHdnwz

Это для .NET 3.5 и использует AnonymousPipeServerStream - но с небольшим отражением, достаточно легко дублировать внутренние работы AnonymousPipeServerStream в .NET 2.0.

Спасибо за вашу помощь shf301 за то, что указали мне API-интерфейс родного канала, который заставил меня заглянуть в документы Microsoft, чтобы лучше понять, что происходит, и, указав, мне нужно было использовать _open_osfhandle, чтобы получить ссылку FILE *.

4b9b3361

Ответ 1

Вы должны сделать это, используя AnonymousPipeStream в .NET 3.5 или выше. Это предоставляет дескриптор через свойство SafePipeHandle, которое вы можете передать на SetStdHandle.

Для .NET 2.0 вам может потребоваться P/Invoke для API неуправляемой трубы.