У меня самая странная проблема, и, скорее всего, я что-то упускаю или не знаю.
Я создал интерфейс / класс C # COM, который для этого вопроса мы назовем его: Ics_obj и Ccs_obj.
В деструкторе объекта я добавил след в отладку вывода:
~Ccs_obj()
{
OutputDebugString("Releasing: "+this.GetHashCode()); // OutputDebugString with p/invoke
}
Я написал для C ++ класс, что Ics_obj является членом этого класса, а этот член является оберткой com_ptr_t для Ics_obj, сгенерированной в .tlh:
class lib_exp_macro cpp_client
{
public:
cpp_client();
~cpp_client();
...
...
Ics_objPtr _csobj; // the Ics_obj* wrapped in com_ptr_t.
}
В конструкторе я создаю экземпляр Ccs_obj, а в деструкторе я освобождаю его. Я также добавил следующие следы:
cpp_client::cpp_client()
{
HRESULT hr = _csobj.CreateInstance( __uuidof( Ccs_obj ) );
if(FAILED(hr)){ /* throw exception */ }
OutputDebugString("Creating client");
}
cpp_client::~cpp_client()
{
OutputDebugString("before releasing _csobj");
}
Теперь я создал 2 экземпляра cpp_client через мой код (создавая их с тем же потоком во время инициализации моего приложения), и я получил 2 следа «Создание клиента».
Проблема в том, что во время выключения я получаю НАРУШЕНИЕ ДОСТУПА, и следы таковы:
before release // first object being released
Releasing: (some number X)
Releasing: (some number Y, Y != X) // <- where did that come from?
before releasing _csobj
SYSTEM CRASH HORRIBLY WITH ACCESS VIOLATION! :-(
Когда я отлаживаю, я получаю НАРУШЕНИЕ ДОСТУПА для доступа к v-таблице COM-объекта.
Кто-нибудь знает, почему я получаю НАРУШЕНИЕ ДОСТУПА? Что я делаю неправильно? Я ДЕЙСТВИТЕЛЬНО ПОТЕРЯЛ ЗДЕСЬ! 🙁
Заранее спасибо!
ОБНОВИТЬ:
С помощью двух ответов (которые были удалены) я понял больше вещей, но у меня все еще есть открытые вопросы …
Первое и самое важное, что второй выпуск был в dllmain PROCESS_DETACH. Когда я переместил код релиза из этого контекста, все было хорошо, но почему я не могу освободить COM-объект в контексте PROCESS_DETACH ?!
В одном из ответов, которые были удалены, говорилось, что CLR .Net отключился, поэтому 2-й выпуск в моих следах. Это имело большой смысл, и это привело меня к выводу выпускающего кода из контекста PROCESS_DETACH, но если это так, и CLR завершает работу, потому что код PROCESS_DETACH, почему я не получаю никаких следов «Releasing: …», если я не освобождаю COM-объект (отсоединяя _com_ptr_t) ??? Или, другими словами, почему CLR не выключается, если я не освобождаю 1-й объект?
Еще раз спасибо за вашу удивительную помощь!
Задача ещё не решена.
Других решений пока нет …