Pull to refresh

.NET unmanaged interop — более продвинутые техники

В этой статье я хотел бы дополнить и уточнить детали некоторых вопросов, описанных здесь

Создание COM out-proc сервера


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

Создать сборку с экспортируемыми COM-типами и зарегистрировать ее в реестре при помощи regasm. Здесь все выполняется точно так же, как для in-proc сервера — только тип выходного файла должен быть EXE. Если теперь попытаться создать COM-объект нашего типа, можно будет наблюдать интересный эффект — EXE-файл, который загружен в процесс как DLL ;)

Чтобы этого избежать, требуется дополнительное действие — добавить запись HKEY_CLASSES_ROOT/CLSID/<GUID класса>/LocalServer32, указывающую путь к нашей сборке. Такая запись нужна для каждого экспортируемого типа. Теперь, если попытаться создать COM-объект — наша сборка будет запущена в отдельном процессе. Однако, вскоре клиентский код выдаст ошибку — «Server execution failed». Причина — отсутствие фабрики объектов (COM class object) в нашей сборке. Каждый COM out-proc сервер должен зарегистрировать ее при запуске с помощью функции CoRegisterClassObject. Если этого не сделать в отведенное время, происходит ошибка.

К счастью, нам не придется возиться с P/Invoke — вся необходимая функциональность уже есть в классе RegistrationServices.
Регистрация фабрики объектов должна вызываться при запуске метода Main нашей сборки, и выглядит примерно так:

var rs = new RegistrationServices();
var cookie = rs.RegisterTypeForComClients(typeof(MyComType),
RegistrationClassContext.RemoteServer | RegistrationClassContext.LocalServer
| RegistrationClassContext.InProcessServer, RegistrationConnectionType.MultipleUse);

Application.Run();

rs.UnregisterTypeForComClients(cookie);

Этот код не совсем полон — необходима обработка блокировок сервера, которая будет автоматически закрывать процесс, когда не останется ни одного активного объекта. Однако, эта задача уже намного очевиднее в решении. Ее можно рассмотреть в отдельной статье, или перейти к другим интересным, но малоизвестным техникам:
  1. Передача управляемых методов для обратного вызова (callback)
  2. Экспорт управляемых методов в неуправляемый код

Решать вам :)
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.