В delphi 6 есть ошибка, которую вы можете найти в Интернете для справки, когда при импорте tlb порядок параметров в вызове события меняется на противоположный. Он инвертируется один раз в импортированном заголовке и один раз в TServerEventDIspatch.Invoke.
Вы можете найти больше информации об этом здесь:
http://cc.embarcadero.com/Item/16496
Отчасти это связано с тем, что в TServerEventDispatch возникает утечка памяти с параметром Variant типа Var_Array (возможно, других, но это более очевидный, который я мог видеть). Код вызова копирует аргументы в VarArray для передачи в обработчик событий, а затем копирует VarArray обратно в аргументы после вызова, соответствующий код вставлен ниже:
// Set our array to appropriate length
SetLength(VarArray, ParamCount);
// Copy over data
for I := Low(VarArray) to High(VarArray) do
VarArray[I] := OleVariant(TDispParams(Params).rgvarg^[I]);
// Invoke Server proxy class
if FServer <> nil then FServer.InvokeEvent(DispID, VarArray);
// Copy data back
for I := Low(VarArray) to High(VarArray) do
OleVariant(TDispParams(Params).rgvarg^[I]) := VarArray[I];
// Clean array
SetLength(VarArray, 0);
В моем случае есть некоторые очевидные обходные пути: если я пропускаю копирование в случае параметра VarArray, это устраняет утечку. чтобы не изменять функциональность, я подумал, что я должен скопировать данные в массив вместо варианта обратно в параметры, но это может стать сложным, поскольку он может содержать другие варианты и мне кажется, что это должно быть сделано рекурсивно.
Поскольку изменение в OleServer будет иметь волновой эффект, я хочу убедиться, что мои изменения здесь строго верны.
Может кто-нибудь пролить свет на то, почему именно здесь просачивается память? Кажется, я не могу посмотреть стека вызовов ниже, чем TServerEventDIspatch.Invoke (почему это так?)
Я полагаю, что в процессе копирования Variant, удерживающего VarArray обратно в список параметров, он добавил ссылку на массив, что не позволило ему быть выпущенным как обычно, но это всего лишь приблизительное предположение, и я не могу отследить код для резервного копирования.
Может быть, кто-то с лучшим пониманием всего этого мог бы пролить свет?