Символ исключен с помощью линкера (Delphi) - PullRequest
1 голос
/ 28 сентября 2010

Помощь!Я получаю эту ошибку при просмотре содержимого параметров входящей функции в моем приложении Delphi 4.

Код вызывает функцию в dll с 3 параметрами (app.handle, pchar, boolean)

Функция объявленияв externs.pas и объявлен как:

function AdjustVoucherDifference(hOwner :HWnd; Receipt_ID :PChar; 
  bCommit: Boolean): boolean; stdcall; 
  external 'FBCoupon.dll' name 'AdjustVoucherDifference';

в другом исходном файле, код вызывает его как:

AdjustVoucherDifference(Application.Handle, PChar(Receipt_ID), true);

При просмотре кода в режиме отладки я вижу действительныйзначений в исходном файле, но когда он разбивается на строку в файле externs.pas, всплывающая подсказка для значений (или CTRL + F7 ) показывает, что символы были удалены изЛинкер и я получаем исключения, когда выполнение находится в dll.

DLL разработана в CBuilder4, и определенная функция объявлена ​​как:

BOOL __stdcall __DLLTYPE__ AdjustVoucherDifference(HWND hOwner, 
  char *receipt_id, bool commit);

Оптимизация компилятора отключена.

Спасибо !!!

Ответы [ 3 ]

4 голосов
/ 28 сентября 2010
  1. Установка точки останова перед вызовом внешней функции (не точка останова во внешнем объявлении).
  2. Открыть окно разборки отладчика. (Я забыл точный путь меню, чтобы добраться туда)
  3. Выполняйте пошаговые инструкции машины. Вам не нужно понимать их все (хотя это не больно), но внимательно следите за инструкциями прыжка и вызова.
  4. Будет немного болтовни, так как код устанавливает параметры для вызова, а затем инструкцию для вызова.
  5. Следуйте инструкциям вызова. Поскольку это внешний вызов, ожидайте увидеть косвенную инструкцию перехода.
  6. Следуйте за этим прыжком к месту назначения. Теперь вы должны быть внутри C ++ DLL. Если вы собрали DLL в CBuilder с отладочной информацией, у вас также должна быть информация о символах и информация об исходной строке.

Если ваши объявления параметров на стороне Delphi не соответствуют ожиданиям на стороне C ++, то вы должны начать видеть, что на стороне C ++ вызова происходят ошибки, которые могут привести к исключению нарушения доступа или времени выполнения ошибка, сгенерированная DLL C ++.

1 голос
/ 28 сентября 2010

Обратите внимание, что BOOL и Boolean различны. BOOL определяется в Windows.pas как

type
  BOOL = LongBool;

, поэтому SizeOf (BOOL) = 4, а SizeOf (Boolean) = 1

Даже если это не поможет вам в вашей проблеме, замените Boolean на BOOL (или LongBool) в объявлении Delphi, чтобы сделать объявление правильным.

1 голос
/ 28 сентября 2010

На компоновщик не влияют оптимизации компилятора.Компоновщик будет «умно ссылаться» на любую подпрограмму, которую он может доказать, никогда не будет вызываться в вашей программе.К сожалению, это означает, что отладчик недоступен для вызова.

Мое решение этого, когда это случилось со мной в прошлом, - это вообще сделать бессмысленный вызов данной подпрограммы в инициализация раздел.Smartlinker не будет связываться с ними.Вы можете сделать это без каких-либо ошибок?

initialization
  AdjustVoucherDifference(0, '', true); //DO NOT SMARTLINK THIS OUT!
end;
...