Является ли COM-интерфейс C++ для импортированного RegExp.tlb неявно разделяющим память между процессами?
Хорошее время. Извините, если мой вопрос странный, но я новичок в том, с чем я столкнулся.
Мой случай в следующем, я использую VB RegExp в C++ через COM следующим образом:
#import "RegExp.tlb" no_namespace
...
void DoSomething() {
...
static IRegExpPtr regExp( __uuidof(RegExp) );
regExp->Pattern = A2BSTR(m_szStrReg); // read on dll load from the file
if ( regExp->Test(someString) ) {
IMatchCollectionPtr matches = regExp->Execute(someString);
// my staff here
...
}
...
}
Мои вопросы:
Я все делаю правильно? (PS Я знаю о CoInit и CoUninit, но вопрос не о них).
Является
regExp
процесс безопасен? Я спрашиваю об этом потому, что у меня есть несколько экземпляров моего класса сDoSomething()
называя это много раз. И у меня есть CRASH в regExp внутренних органов. Вызвано повреждением кучи / неверным доступом к памяти случайно при разных вызовах методов regExp с разными аргументами.
Я проверил значение указателя regExp, regExp->Pattern.GetAddress() и так далее. И они разные в разных процессах. Но когда я добавил имя Mutex и завернул DoSomething()
с этим добавление межпроцессной синхронизации - Авария исчезла. Вот почему я спрашиваю, имеет ли regExp что-то неявно разделяемое между процессами?
1 ответ
Ваш код имеет дело с указателем интерфейса COM, живущего в текущей квартире. Вы уже знаете об инициализации COM, поэтому текущая квартира означает текущий поток, если вы находитесь в STA, в частности. Вам гарантируется, что методы указателя интерфейса могут быть вызваны, но внутренняя сторона этого указателя интерфейса может отличаться: это может быть реализация напрямую или вспомогательный объект (прокси), который передает вызов в квартиру, где находится фактический объект, Последнее, в частности, может быть в другом процессе.
Это все потокобезопасно и "безопасно". Параметры берутся с вызовом к реальному объекту и затем передаются обратно. Вызывающему не нужно заботиться о том, имеет ли он дело с реальным объектом или прокси-сервером, и вызывающему также не нужно знать, вызывается ли он фактическим вызывающим или вспомогательной заглушкой.
Сказав это, фрагмент кода выше это хорошо. У аварии, которая у вас была, должна быть другая причина.