Лучший способ вызова 32-битного неуправляемого кода из 64-битного управляемого кода с использованием обертки управляемого кода
Частота, с которой я сталкиваюсь с ситуацией, когда я должен вызвать собственный 32-разрядный код из управляемого 64-битного процесса, возрастает по мере того, как распространены 64-разрядные машины и приложения. Я не хочу отмечать мое приложение как 32-битное, и я не могу получить 64-битные версии кода, который вызывается.
Решением, которое я использую в настоящее время, является создание прокладок С++ COM, которые загружаются из процесса, чтобы 32-разрядные вызовы выполнялись из 64-битного процесса.
Это решение COM-прокладки работает хорошо, а вызовы перекрестных процессов обрабатываются за кулисами COM, что минимизирует накладные расходы этого подхода.
Я хотел бы сохранить все новые разработки, которые мы предпринимаем с помощью С#, и задался вопросом, есть ли какие-либо рамки, которые минимизируют накладные расходы на это. Я посмотрел на IPCChannel, но я чувствую, что этот подход не настолько опрятен, как решение COM-прокладки.
спасибо,
Ed
Ответы
Ответ 1
У меня была та же проблема, и моим решением было использовать remoting. В основном проект состоял из:
- Независимая от платформы библиотека
CalculatorRemote.dll
с
-
CalculatorNative
внутренний статический класс с методами x32 P/Invoke
-
RemoteCalculator
класс, полученный из MarshalByRefObject
, в котором используются собственные методы из CalculatorNative
;
- Основная независимая от платформы библиотека С# (например,
Calculator.dll
), ссылающаяся на CalculatorRemote.dll
, с классом Calculator
, которая была конфиденциально с использованием singleton класса RemoteCalculator
для вызова функций x32, где это необходимо;
Консольное приложение - x32, которое размещало
RemoteCalculator
from CalculatorRemote.dll
для использования Calculator.dll
через IpcChannel
.
Итак, если основное приложение запустилось в режиме x64, оно создало хост-приложение RemoteCalculator
и использовало удаленный экземпляр RemoteCalculator
. (Когда в x32 он просто использовал локальный экземпляр RemoteCalculator
.) Трудная часть говорила, что приложение-калькулятор-хост закрывается.
Я думаю, что это лучше, чем использование COM, потому что:
- Вам не нужно регистрировать COM-классы в любом месте;
- Взаимодействие с COM должно быть медленнее, чем удаленный .NET;
- Иногда, если что-то не так на стороне COM, вам необходимо перезапустить приложение, чтобы восстановить его; (возможно, я просто не очень знаком с COM)
- При работе в режиме x32 не будет никакого штрафа за производительность при удалении - все методы будут вызываться в том же AppDomain.
Ответ 2
В значительной степени единственный ответ - вне коммуникаций. Вы можете создать проект .NET, который представляет собой 32-разрядный исполняемый файл, который делает все необходимые 32-битные вызовы и связывается с ним через сообщения Windows, WCF, именованные каналы, файлы с памятью (4.0) и т.д. Я уверен это то, как Paint.NET делает WIA (Windows Imaging Acquisition) из 64-битного процесса.
В случае PDN они просто передают имя файла, который они ожидают в качестве вывода, но более сложная связь не представляет сложности. Это может быть лучший способ пойти в зависимости от того, что вы делаете.