Оказывается, что проблема с вылетом в методе OlePropertySet имеет широкое распространение в разных версиях C++Builder от 6.0 до 2007 (см. Google с запросом "OlePropertySet violation") и с разными проектами.
Расследование показывает, что в общем виде проблема в следующем: при использовании в проекте шаблона класса TAutoDriver<IDispatch>, C++Builder генерит код для этого шаблона с учетом размера объекта, отличающегося от того, который используется в недрах Vcl, в т.ч. в реализации метода Variant.OlePropertSet.
Код для Variant::OlePropertySet выглядит следующим образом:
// кусок CBuilder6\Source\Vcl\variant.cpp
void Variant::OlePropertySet(const String& name, TAutoArgsBase& args)
{
// Bind to IDispatch in this Variant
//
TAutoDriver<IDispatch> disp;
disp.Bind(*this /* operator LPDISPATCH() AddRef()s already */, false);
// Look up the dispid of the name passed
//
DISPID id;
OleCheck(disp.GetIDsOfNames(WideString(name), id));
// Do Invoke
//
OleCheck(disp.OlePropertyPut(id, args));
}
Как только TAutoDriver<IDispatch> встречается в нашем проекте, C++Builder скомпилирует его код c учетом настроек нашего проекта, а линкер включит именно эту версию реализации в исполняемый модуль, ОДНАКО размер объекта в этом случае оказывается на 4 байта меньше (если использовать стандартные настройки компиляции, предложенные по-умолчанию) и члены класса имеют иное смещение, чем те, что используются в коде Variant.OlePropertySet.
С автосгенеренном C++Builder'ом файле ZuluOcx_OCX.h встречается использование TAutoDriver<> с dispinterface'ами, а значит проблема инициируется.
Подобная проблема с TAutoDriver<IDispatch> также описывается в Borland Developer Network на Quality Central (см.
qc.borland.com/wc/qcmain.aspx?d=55110), а также здесь (
helpdesk.ingeardrivers.com/supportsuite/index.php?_m=knowledgebase&_a=viewarticle&kbarticleid=48).
Там предлагается изменить настройки проекта, убрав опцию "Zero length empty base class" параметрах C++, однако мне в тестовом проекте этот рецепт не помог (размер "нашего" TAutoDriver'а стал наоборот на 4 байта больше, чем в Vcl).
Я вышел из положения так: включил текст метода Variant::OlePropertySet (см. код выше) в тело своего проекта, заставив его тем самым скомпиляться с моими настройками проекта (и не зависить от них вообще) и все заработало...
При этом в параметрах Packages в настройках проекта я отключил флажок "Build with run-time packages"...