IRegExp2, проблема Access Violation при Replace

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Koduc
Сообщения: 22
Зарегистрирован: 10 сен 2007, 01:33
Контактная информация:

25 окт 2007, 13:02

Может или я чего не понимаю или так и должно быть..

Код: Выделить всё

CoInitialize(NULL);

IRegExp2 *pMyRegExp;
CoCreateInstance(CLSID_RegExp, NULL, CLSCTX_ALL, IID_IRegExp2, (void **)&pMyRegExp);

pMyRegExp->set_Global(VARIANT_FALSE);
pMyRegExp->set_IgnoreCase(VARIANT_TRUE);

CComBSTR patern(L"gg");
CComBSTR bstrInput(L"dkghbdjg fjjwo4583rg sfgs gghdkjhe");
CComBSTR replace(L"GG");
CComBSTR bstrOutput;

pMyRegExp->set_Pattern(patern);

VARIANT varReplace;
VariantInit(&varReplace);
varReplace.vt      = VT_BSTR;
varReplace.bstrVal = replace;

pMyRegExp->Replace(bstrInput, varReplace, &bstrOutput); 
pMyRegExp->Release();

CoUninitialize();
При вызове pMyRegExp->Replace получаю First-chance exception in struct.exe (KERNEL32.DLL): 0xC0000005: Access Violation.
Хотя замена срабатывает и получается результат нужный, но.. "Неаккуратненько как-то" (с)
В чем проблема может быть?
При работе с классом, который описан http://rsdn.ru/Forum/message/1356701.1.aspx выдает такую же ошибку..
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

23 ноя 2007, 11:07

В VARIANT BSTR-строку нужно откопировать, а не присвоить указатель. Советую использовать класс _variant_t, он сам это сделает. Кстати, если используешь CComBSTR, то для однородности можно использовать для варианта CComVariant. Он также умеет делать копирование BSTR строк с помощью конструктора копирования и перегрузки оператора =.

Ещё одно замечание. Вместо IRegExp2* советую использовать смарт поинтер. Например ATL-евский CComPtr<IRegExp2>. В этом случае не придётся заботить о вызове Release и вместо COM функции CoCreateInstant можно будет вызвать метод этого смартпоинтера CreateInstane, которому нужно передать только один параметр - CLSID кокласса.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Koduc
Сообщения: 22
Зарегистрирован: 10 сен 2007, 01:33
Контактная информация:

03 дек 2007, 23:44

Код: Выделить всё

CComBSTR patern(L"gg");
	CComBSTR bstrInput(L"dkghbdjg fjjwo4583rg sfgs gghdkjhe");
	CComBSTR replace(L"GG");
	CComBSTR bstrOutput;

	CComPtr <IRegExp2> pMyRegExp;

	pMyRegExp.CoCreateInstance(CLSID_RegExp);
	pMyRegExp->put_Pattern(patern);

	CComVariant varReplace;
	VariantInit(&varReplace);
	//varReplace.vt      = VT_BSTR;
	//varReplace.bstrVal = replace;
	varReplace = replace;

	pMyRegExp->Replace(bstrInput, varReplace, &bstrOutput);
Странно, но факт, что ошибка в кернеловском модуле:
First-chance exception in test_my.exe (KERNEL32.DLL): 0xC0000005: Access Violation
Программа продолжает работу, в bstrOutput имеем правильный результат.. При чем что с IRegExp, что с IRegExp2 имеем одинаковую ошибку.. Сколько не спрашивал - никто о таком не знает, у всех вроде полет нормальный.. Чего я не так делаю? :)
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

03 дек 2007, 23:50

А CoInitialize делал?
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

04 дек 2007, 12:16

Ну в конце-концов может быть просто глюки в системных библиотках. Если наружу не летит, то и волноваться не стоит. Мелкомягкие всегда славились чистотой кода.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Koduc
Сообщения: 22
Зарегистрирован: 10 сен 2007, 01:33
Контактная информация:

04 дек 2007, 22:39

Понятно.. Просто неприятно, это оно может сейчас и здесь наружу не лететь, а в Самый Отвественный Момент вылезет ;)
Спасибо за внимание к моей проблеме!
Ответить