COM & CoGetClassObject () - PullRequest
       1

COM & CoGetClassObject ()

3 голосов
/ 20 июля 2011

У меня небольшая проблема с CoGetClassObject().

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

Итак, я начинаю подключать CoCreateInstance() и loadLibrary(), что, я думаю, хорошо.Проблема заключается в том, что загружены библиотеки DLL в двух версиях.

Так что я думаю, что CoGetClassObject() - это проблема / решение, поскольку она предоставляет указатель на интерфейс объекта, связанного с CLSID, содержащим библиотеку DLL, котораяприложение должно использовать более старую версию.

Но я не знаю, что "делает" эта функция, так как я могу "переопределить" эту функцию?

спасибо.

PS: я новичок в программировании COM.

Ответы [ 3 ]

4 голосов
/ 20 июля 2011

CoGetClassObject () просто выполняет половину работы, которую выполняет CoCreateInstance ().Возвращает фабрику классов.Затем CoCreateInstance () вызывает IClassFactory :: CreateInstance () и освобождает IClassFactory.Вы будете использовать его только в том случае, если вам необходимо создать много объектов определенного кокласса и вы хотите оптимизировать это.Это позволяет избежать затрат на создание и выпуск фабрики снова и снова.

Возможно, вы упускаете из виду гораздо более простое решение этой проблемы.Вы можете просто скопировать новую версию DLL-библиотеки COM-сервера в тот же каталог, что и EXE-файл клиента.И создайте файл нулевого байта с именем "app.exe.local", где "app" - это имя EXE-файла.Этого достаточно, чтобы принудительно загрузить скопированную DLL вместо той, на которую указывает реестр.Статья MSDN Library о перенаправлении DLL находится здесь .

0 голосов
/ 20 июля 2011

Если вы хотите загрузить определенную COM DLL, независимо от того, установлена ​​ли более новая версия, и независимо от того, где находится более старая DLL, просто игнорируйте CoCreateInstance() и CoGetClassObject() в целом. Загрузите старую DLL самостоятельно через LoadLibrary(), затем вызовите ее экспортированную функцию DllGetClassObject() напрямую, чтобы получить интерфейс DLL IClassFactory, затем при необходимости вызовите IClassFactory::CreateInstance(). Это все CoCreateInstance() и CoGetClassObject(), так или иначе, внутренне, но это позволяет обойти запросы реестра, которые они выполняют, чтобы определить путь к DLL для загрузки.

0 голосов
/ 20 июля 2011

Очень простое объяснение: CoGetClassObject() открывает HKCR\CLSID\{ClassId} и смотрит на InProcServer32 или LocalServer32 в зависимости от того, какое значение CLSCTX_* передано - это путь к COM-серверу.

Как только он находит путь к файлу COM-сервера, загружается (LoadLibraryEx() с флагом LOAD_WITH_ALTERED_SEARCH_PATH в случае in-proc или CreateProcess() в случае out-proc) COM-сервер. Затем он находит и вызывает DllGetClassObject() для серверов in-proc или ожидает, пока фабрика классов не будет зарегистрирована для серверов out-proc.

Это, конечно, игнорирует такие вещи, как DCOM и т. Д. Вы можете получить лучшее представление о том, как он пересекает реестр, используя утилиту Process Monitor.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...