Как я могу передавать данные из управляемой сборки в родную библиотеку и обратно?
Как я могу передать данные (текст) из управляемой сборки в собственную библиотеку и передать данные (текст) обратно на управляемую сборку?
В частности, я хочу показать 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 *
.
Ответы
Ответ 1
Вы должны сделать это, используя AnonymousPipeStream в .NET 3.5 или выше. Это предоставляет дескриптор через свойство SafePipeHandle
, которое вы можете передать на SetStdHandle
.
Для .NET 2.0 вам может потребоваться P/Invoke для API неуправляемой трубы.
Ответ 2
Вы можете использовать ссылку ниже. Он имеет пример реализации и класс оболочки IStream.
http://csharpexamples.com/c-istream-implementation-and-istream-wrapper-class-example/