Я перефразировал этот вопрос.
Когда объекты .net подвергаются COM-клиентам через COM iterop, создается CCW (COM Callable Wrapper), это находится между COM-клиент и управляемый .net-объект.
В мире COM объекты сохраняют количество ссылок, которое ему принадлежат другие объекты. Объекты удаляются/освобождаются/собираются, когда этот счетчик ссылок переходит в нуль. Это означает, что окончание COM-объекта является детерминированным (мы используем использование /IDispose в .net для детерминированного завершения, финализаторы объектов не детерминированы).
Каждый CCW является COM-объектом, и эта ссылка считается как любой другой COM-объект. Когда CCW умирает (счетчик ссылок идет до нуля), GC не сможет найти объект CLR, который обернут CCW, и объект CLR имеет право на сбор. Счастливые дни, все хорошо с миром.
То, что я хотел бы сделать, - это поймать, когда CCW умирает (т.е. когда его счетчик ссылок идет на ноль) и каким-то образом сигнализирует об этом объекту CLR (например, вызывая метод Dispose на управляемом объекте).
Итак, можно ли узнать, когда счетчик ссылок COM Callable Wrapper для класса CLR переходит в нуль?
и/или
Возможно ли предоставить мою реализацию AddRef и ReleaseRef для CCW в .net?
Если нет альтернативы, чтобы реализовать эти DLL в ATL (мне не нужна помощь с ATL, спасибо). Это не будет наука о ракете, но я неохотно это делаю, поскольку я единственный разработчик в доме с любым реальным С++ или любым ATL.
Фон
Я переписываю некоторые старые VB6 ActiveX DLL в .net(С#, если быть точным, но это скорее проблема с .net/COM-взаимодействием, а не с проблемой С#). Некоторые из старых объектов VB6 зависят от подсчета ссылок для выполнения действий, когда объект завершается (см. Объяснение подсчета ссылок выше). Эти DLL не содержат важной бизнес-логики, это утилиты и вспомогательные функции, которые мы предоставляем клиентам, которые интегрируются с нами с помощью VBScript.
Что я не пытаюсь сделать
- Вместо этого ссылаются объекты .net. использования сборщика мусора. Я вполне доволен GC, мой проблема не в GC.
- Используйте финализаторы объектов. Финализаторы не детерминированным, в этом случае я необходимо детерминированное прекращение (например, использование /IDispose в .net)
- Внедрение IUnknown в неуправляемом С++
Если мне нужно перейти на С++-маршрут, я буду использовать ATL, спасибо. - Решите это с помощью Vb6 или повторно используйте Объекты VB6. Весь смысл это упражнение - удалить нашу сборку зависимость от Vb6.
Спасибо
BW
Принятый ответ
Люди из тысячи благодаря Steve Steiner, которые придумали единственный (возможно, работоспособный) ответ на основе .net и Earwicker, который придумал очень простое решение ATL.
Однако принятый ответ идет на Bigtoe, который предлагает обернуть объекты .net в объектах VbScript (которые я не считал честными), эффективно предоставляя простое решение VbScript для проблемы с VbScript.
Спасибо всем.