Лучший способ вызова 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 они просто передают имя файла, который они ожидают в качестве вывода, но более сложная связь не представляет сложности. Это может быть лучший способ пойти в зависимости от того, что вы делаете.