Как работает это странное 32-битное / 64-битное решение взаимодействия?

В настоящее время я обслуживаю часть программного обеспечения, которую мы передали на аутсорсинг пару лет назад и которая плохо документирована. Это COM-сервер для использования сторонними приложениями и установщик, который выполняет все необходимое развертывание.

Ядро скомпилировано как 32-битная DLL и предназначено для использования из 32-битных приложений. Также есть прокладка, скомпилированная как 64-битная DLL и предназначенная для использования из 64-битных приложений. Прокладка вызывает CoCreateInstance () для создания экземпляра ядра и перенаправляет вызовы в ядро. Ядро зависит от огромного набора других 32-битных библиотек.

32-разрядное ядро ​​регистрируется точно так же, как обычно внутри процесса - в разделе HKCR \ CLSID есть запись, которая включает идентификатор основного класса и путь к библиотеке в InprocServer32. 64-битная оболочка регистрируется таким же образом, а также для 64-битной оболочки вводится идентификатор приложения - он добавляется в HKCR \ CLSID, а также регистрируется в DCOM - в консоли DCOM есть запись с этим идентификатором приложения.

Сейчас регистрация DCOM выглядит странно. Почему прокладка должна быть зарегистрирована в DCOM, а не в ядре? Я ожидаю, что 32-битное ядро ​​должно быть зарегистрировано в DCOM для создания экземпляра в отдельном процессе и защиты от 64-битного потребителя. Но, видимо, работает так, как сейчас. Какой смысл регистрировать в DCOM 64-битную прокладку, а не 32-битное ядро?


person sharptooth    schedule 09.11.2009    source источник
comment
Я не знаю, уместно ли это понимать, но не забывайте, что 32-битные приложения и 64-битные приложения имеют разные представления реестра. Используя отражение, когда 32-битное приложение пытается открыть HKCR \ ..., оно фактически открывает HKCR \ Wow6432Node \ ... Таким образом, регистрационная информация, используемая 32-битными приложениями, находится в HKCR \ Wow6432Node \ CLSID \ {clsid}, а для 64-битных приложений его под HKCR \ CLSID \ {clsid} (конечно, используя 64-битную программу просмотра реестра).   -  person Chris Becke    schedule 09.11.2009
comment
Изменения, которые я описал в вопросе, есть в обеих ветках.   -  person sharptooth    schedule 09.11.2009


Ответы (1)


Напомним, что вы можете комбинировать 32-битные и 64-битные библиотеки DLL и процессы. 32-битное ядро ​​в этом случае не использует DCOM, потому что оно может быть загружено непосредственно в 32-битный процесс хоста. Для 64-разрядной оболочки требуется DCOM, потому что ее разработчики пользуются возможностью COM размещать ядро ​​в отдельном процессе, даже на одном компьютере. Это необходимо, поскольку 32-битное ядро ​​не может быть загружено на 64-битный хост. При использовании DCOM все вызовы к ядру и от него выполняются в отдельном 32-битном процессе. Это оптимальная схема, поскольку вызовы в ядро ​​не проходят через DCOM. Разработчики, скорее всего, воспользовались этим в своем тестировании, отладке в 32-битном процессе без вмешательства DCOM, пока не было доказано, что ядро ​​работает достаточно хорошо, чтобы попытаться вызвать его из 64-битного приложения.

person iantr    schedule 10.11.2009
comment
Я до сих пор не понимаю этого полностью. Когда COM + используется для тех же целей, 32-разрядный компонент обычно помещается в приложение COM +. Затем 64-битный потребитель вызывает CoCreateInstance (), вызов маршрутизируется через COM +, COM + запускает 32-битный суррогатный процесс, загружает туда компонент, запускает маршаллинг, и все работает. С COM + потребитель является 64-битным, а 32-битный компонент помещается в приложение COM +. - person sharptooth; 10.11.2009
comment
А почему здесь по-другому? Как я понял, 64-битный потребитель вызовет CoCreateInstance (), 64-битный процесс будет запущен под DCOM в другом отдельном процессе. А вот как последний будет загружать 32-битное ядро ​​- ядро ​​не под DCOM. Вот чего я действительно не понимаю. - person sharptooth; 10.11.2009