链接器删除符号(Delphi)

时间:2010-09-27 22:15:19

标签: c delphi dll external

帮助! 在Delphi 4应用程序中查看入站函数参数的内容时,我收到此错误。

代码使用3个参数(app.handle, pchar, boolean)

调用dll中的函数

声明函数在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 个答案:

答案 0 :(得分:4)

  1. 在调用外部函数之前设置断点(不是外部声明的断点)。
  2. 打开调试器反汇编窗口。 (我忘记了到达那里的确切菜单路径)
  3. 逐个查看机器说明。你不需要了解所有这些(虽然没有伤害),但要注意跳转和通话指令。
  4. 当代码设置呼叫的参数,然后是呼叫指令时,会有一些喋喋不休。
  5. 跟随(进入)呼叫指令。由于这是一个外部调用,因此希望看到跳转间接指令。
  6. 跟随跳转到目的地。您现在应该在C ++ DLL中。如果您使用调试信息在CBuilder中构建DLL,则还应该有符号信息和源代码行信息。
  7. 如果你在Delphi端的参数声明与C ++方面的期望不符,那么你应该开始看到调用的C ++端出现问题,这可能导致访问冲突异常或运行时C ++ DLL生成的错误。

答案 1 :(得分:1)

链接器不受编译器优化的影响。链接器将“智能链接”任何它可以证明永远不会在程序中调用的例程。不幸的是,这意味着调试器无法调用它。

我的解决方案,当我过去发生这种情况时,通常会在初始化部分对有问题的例程进行无意义的调用。 smartlinker不会搞砸那些。你能做到这一点而不会造成任何错误吗?

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

答案 2 :(得分:1)

请注意,BOOL和布尔值不同。 BOOL在Windows.pas中定义为

type
  BOOL = LongBool;

所以SizeOf(BOOL)= 4而SizeOf(布尔)= 1

即使它对你的问题没有帮助,在Delphi声明中用BOOL(或LongBool)替换布尔值,使声明正确。