Falcrum (falcrum) wrote,
Falcrum
falcrum

А вот кто ещё помнит седьмой Delphi?

Коллегу попросили слегка поколупаться в старом проекте:



Приходит ко мне - грит, я в шоке: убил полдня - задница! Ничего не понимаю! Не работает! Давай вместе посмотрим!

Итак, имеется DLL-ка, в ней две функции:

Load1: function (aS: pChar): boolean; stdcall = nil;
Load2: function (aS: pChar; var codeErr: LongInt): boolean; stdcall = nil;


Инициализация:

@Load1 := GetProcAddress (hLib, 'Load1');
@Load2 := GetProcAddress (hLib, 'Load2');


Вызов Load1:

procedure PerformLoad (TaskObject: TTaskObject);
var
ErrorCode: integer;
s: string;
begin
s := TaskObject.RequestText;
if Load1 (@s[1]) then // вызов старой функции библиотеки
ErrorCode := 0
else
ErrorCode := 1;
TaskObject.ErrorCode := ErrorCode;
end;


Вызов снаружи:

// Инициализация объекта LocalTaskObject
...
PerformLoad (LocalTaskObject);
if (LocalTaskObject.ErrorCode = 0) then
...


Всё работало. Но. Надо ему было заменить Load1 на Load2:

procedure PerformLoad (TaskObject: TTaskObject);
var
ErrorCode: Integer;
s: string;
begin
s := TaskObject.RequestText;
Load2 (@s[1], ErrorCode); // вызов новой функции библиотеки
TaskObject.ErrorCode := ErrorCode;
end; //Вот здесь ещё всё хорошо - объект TaskObject в отладчике "живой"


И внезапно:

// Инициализация объекта LocalTaskObject
...
PerformLoad (LocalTaskObject); // передаём "живой" объект
if (LocalTaskObject.ErrorCode = 0) then // и внезапно вот здесь LocalTaskObject становится nil
...


Увидев подобное, я несколько прифигел. В чём разница? Что может освобождать или затирать объект? Ладно, говорю, давай попробуем тупой костыль:

function PerformLoad (TaskObject: TTaskObject): TTaskObject;
var
ErrorCode: integer;
s: string;
begin
s := TaskObject.RequestText;
Load2 (@s[1], ErrorCode); // вызов новой функции библиотеки
TaskObject.ErrorCode := ErrorCode;
result := TaskObject;
end;
// Вызов
// Инициализация объекта LocalTaskObject
...
LocalTaskObject := PerformLoad (LocalTaskObject); // передаём "живой" объект
if (LocalTaskObject.ErrorCode = 0) then // и внезапно всё опять заработало
...


Но как?
Tags: КровавыйЭнтерпрайз, Размышлизмы
Subscribe
  • Post a new comment

    Error

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 14 comments