开发者

Symbol eliminated by linker (Delphi)

Help! I am receiving this error when viewing the contents of an inbound function parameters in my Delphi 4 application.

The code calls a function in a dll with 3 parameters (app.handle, pchar, boolean)

The declaring function is in externs.pas and开发者_运维技巧 declared as:

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

in another source file, the code calls it as:

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

When stepping through the code in debug mode, I can see valid values in the source file, but when it breaks on the line in externs.pas, the tooltip for the values (or CTRL+F7) shows that the symbols have been eliminated from the linker and I receive exceptions when the execution is in the dll.

The DLL is developed in CBuilder4 and the particular function is declared as:

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

Compiler optimization is turned off.

Thanks!!!


  1. Set a breakpoint before the call to the external function (not a breakpoint on the external declaration).
  2. Open the debugger disassembly window. (I forget the exact menu path to get there)
  3. Step through the machine instructions one at a time. You don't need to understand all of them (though it doesn't hurt), but keep a sharp eye out for jump and call instructions.
  4. There will be a bit of chatter as the code sets up the parameters for the call, then a call instruction.
  5. Follow (step into) the call instruction. Since this is an external call, expect to see a jump indirect instruction.
  6. Follow that jump to its destination. You should now be inside the C++ DLL. If you built the DLL in CBuilder with debug info, you should have symbol info and source line info as well.

If your parameter declarations on the Delphi side don't match the expectations on the C++ side, then you should start to see things going awry on the C++ side of the call, which could lead to an access violation exception or a runtime error generated by the C++ dll.


The linker isn't affected by compiler optimizations. The linker will "smartlink out" any routine that it can prove is will never be called in your program. Unfortunately, this means it's not available for the debugger to call into.

My solution to this, when it's happened to me in the past, is generally to put a meaningless call to the routine in question in an initialization section. The smartlinker won't mess with those. Can you do this without causing any errors?

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


Note that BOOL and Boolean are different. BOOL is defined in Windows.pas as

type
  BOOL = LongBool;

so SizeOf(BOOL) = 4 while SizeOf(Boolean) = 1

Even if it would not help you with your problem, replace Boolean by BOOL (or LongBool) in Delphi declaration to make the declaration correct.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜