古怪的编译器--->Delphi 4(这个错误它怎么知道的?)(0分)

  • 主题发起人 主题发起人 Another_eYes
  • 开始时间 开始时间
A

Another_eYes

Unregistered / Unconfirmed
GUEST, unregistred user!
做了一个dll: TestDll, exports了三个函数:
function func1: THandle;
stdcall;
function func2(handle: THandle): boolean;
stdcall;
function func3(handle: THandle): boolean;
stdcall;
在这个dll中定义了一个类:
TMyClass = class(TComponent)
public
str: string;
......
end;

function func1: THandle;
begin
result := integer(pointer(TMyClass.Create(Application)));
end;

function func3(handle: THandle): boolean;
begin
result := false;
if handle = 0 then
exit;
TMyClass(TObject(ptr(handle))).Free;
result := true;
end;

function fun2(handle: THandle): boolean;
var
myclass: TMyClass;
begin
result := false;
if handle = 0 then
exit;
myclass := TMyClass(TObject(ptr(handle)));
with myclassdo
begin
str := 'Test String';
......
end;
result := true;
end;

另做了个form调用这个dll, form上只有一个button.
button.Onclick:
var
f1, f2: integer;
func1: function : Integer;
stdcall;
func2: function (handle: Integer): boolean;
stdcall;
func3: function (handle: Integer): boolean;
stdcall;
begin
f1 := loadlibrary('TestDll.dll');
if f1 <> 0 then
begin
@func1 := GetProcAddress(f1, 'func1');
@func2 := GetProcAddress(f1, 'func2');
@func3 := GetProcAddress(f1, 'func3');
f2 := func1;
func2(f1);
// 当时不小心写错了, 应该传入f2的
........... // 释放....
end;
end;
两个程序分别编译通过.
在调试testdll时一个有趣的现象发生了:
function fun2(handle: THandle): boolean;
var
myclass: TMyClass;
begin
result := false;
<---断点在此, 开始单步运行
if handle = 0 then
exit;
myclass := TMyClass(TObject(ptr(handle)));
<----此步无法跟踪, 直接跳过了,
断点设在这里的话重新编译时编译器说是无效断点, 被优化掉了.
with myclassdo
begin
str := 'Test String';
<------ 这里出错, 访问冲突
......
end;
result := true;
end;

后来发觉是主程序中写错了, 改正之后, dll中不管断点设在哪句编译器都认为正确.
现在的问题是:
在dll编译过程中它怎么知道调用者的参数是错的?
为什么会把 myclass := TMyClass(TObject(ptr(handle)));
这句上的
断点优化掉????
它怎么知道这句是无效的??????
当我改正主程序之后它又是怎么知道调用者的参数是正确的, 又认为这句有效, 允许设置
断点?(主程序是单独编译的呀? 而且加载dll用的是动态加载和释放)
有点见鬼了的感觉.
 
我所遇到的问题是有些正常的语句也会被优化掉,重新rebuild才行.
 
你说的情况,能再现吗(把主程序再改回去,还能出现你说的情况吗?)?
如果能,那真是太奇怪了,如果没有,应该是menxin说的情况吧.
 
redforks, 最近抽空再现了一次.
知道原因了(我认为知道了).
exe build完后用reopen打开了dll的dpr进行了编译和调试. 估计delphi中保留了原先那个
exe的编译信息. 编译dll时可能用到了那些信息吧.
生成完exe后关闭delphi, 重新打开delphi并编译dll则上述现象消失.
 
接受答案了.
 
后退
顶部