Безопасно ли использовать COM Callable Wrapper, чтобы избежать проблем при передаче GCHandles через домены приложений?

В.NET существует относительно хорошо известная проблема хранения управляемых объектов в неуправляемом коде как gcroot<ManagedObject> обеспечить обратные вызовы из неуправляемого кода: неуправляемый код не знает, какой AppDomain использовать при обращении к управляемому коду, и иногда он выбирает неправильный код, что приводит к ошибкам "Невозможно передать GCHandle через AppDomains".

Стандартное решение проблемы - использование указателя на функцию для делегата, поскольку делегат можно использовать для "запоминания" правильного домена приложения: см. http://lambert.geek.nz/2007/05/29/unmanaged-appdomain-callback/ для полного объяснения.

Однако это решение немного сложнее и требует тщательного управления временем жизни Delgate.

Кажется, что использование COM Callable Wrapper для управляемого объекта работает так же хорошо: вместо сохранения gcroot<ManagedObject>сохранить указатель как IUnknown * с помощью GetIUnknownForObject:

m_value =
   static_cast<IUnknown*> (Marshal::GetIUnknownForObject(value).ToPointer());

Тогда мы можем сделать обратный перевод с GetObjectForIUnknown прежде чем сделать обратный звонок. Недостатком является потеря безопасности типа, потому что IUnknown * теряет фактический тип объекта, и вам позже придется снизить, используя что-то вроде

IDisposable^ value =
      (IDisposable^) (Marshal::GetObjectForIUnknown(IntPtr(m_value)));

где m_value это IUnknown*, но это кажется небольшой ценой.

Я попробовал это, и, кажется, работает нормально в моем случае использования, но есть ли какие-то ошибки с таким подходом? Кажется, что это применимо везде, где можно использовать делегатское решение, поэтому мне интересно, что я что-то упустил из этого.

1 ответ

Решение

Сейчас я использую этот подход в производстве в течение нескольких месяцев без каких-либо проблем, о которых сообщалось, поэтому, хотя он не является окончательным, я хочу сделать предварительный вывод, что этот подход является безопасным.

Другие вопросы по тегам