Delphi-程序未能完成,但使用“可正常工作”;showmessage";之间
我甚至不知道该怎么问这个问题,因为我不知道它是否与执行时间、应用程序进程、消息过程或其他任何事情有关 我(对我来说)遇到了一些奇怪的情况,程序无法运行并在运行时引发系统异常,而如果我将“showmessage”放在中间(这样我就可以很快看到中间发生了什么。不知何故,我更喜欢这种方式而不是手表…) 我不确定代码是否重要,但我将在下面给出:Delphi-程序未能完成,但使用“可正常工作”;showmessage";之间,delphi,Delphi,我甚至不知道该怎么问这个问题,因为我不知道它是否与执行时间、应用程序进程、消息过程或其他任何事情有关 我(对我来说)遇到了一些奇怪的情况,程序无法运行并在运行时引发系统异常,而如果我将“showmessage”放在中间(这样我就可以很快看到中间发生了什么。不知何故,我更喜欢这种方式而不是手表…) 我不确定代码是否重要,但我将在下面给出: procedure LoadSettings; var SettingsBuffToLoad: TStringList; begin SettingsBuf
procedure LoadSettings;
var SettingsBuffToLoad: TStringList;
begin
SettingsBuffToLoad:=TStringList.Create;
Encoding:=TEncoding.ANSI;
SettingsBuffToLoad.LoadFromFile('bin/settings.txt', Encoding);
// showmessage(settingsbufftoload.Strings[0]);
SettingsBuffer:=Decode(SettingsBuffToLoad);
// showmessage(settingsbuffer.Strings[0]); //decode
end;
解码过程声明为外部过程,并从dll中读取
如果我只是删除那些“/”,使其成为代码而不是注释,那么它就可以正常工作。但是,正如您现在看到的,set会引发异常,但在该过程已经完成之后。(调试器的最后一个断点在“end;”处停止,但在继续之后它会引发异常,而不是显示表单;此过程被称为FormCreate过程中的最后一件事
是否与ShowMessage解决的时间有关,或者…?:/
更新:
解码功能,如所要求:
这是如何声明的,就在表单的实现和变量上方:
函数解码(Buff:TStringList):TStringList;StdCall;外部“bin\settings.txt”
这在dll中:
function Decode(Buff: TStringList): TStringList; export;
var
t, u, h: integer;
s: String;
begin
DecodeBuffer.Clear;
DecodeBuffer:=Buff;
for h := 0 to DecodeBuffer.Count-1 do
begin
s := DecodeBuffer.Strings[h];
t := Length(s);
if t > 0 then
begin
for u := 0 to t-1 do
begin
s[u+1] := DecodeChar(s[u+1], (h mod 5) + 1);
end;
DecodeBuffer.Strings[h] := s;
end;
end;
Result:=DecodeBuffer;
end;
这段代码是在一个问题中讨论的,并且是从Remy的回答中使用的。我认为DecodeChar在这里根本不重要,或者是
此外,保存设置的功能也同样适用,该功能在FormClose事件中调用:
这是:
procedure TScribbles.SaveSettings;
var SettingsBuffToSave: TStringList;
begin
SettingsBuffToSave:=TStringList.Create;
Encoding := TEncoding.ANSI;
// Showmessage(settingsbuffer.Strings[0]);
SettingsBuffToSave:=Encode(SettingsBuffer);
// Showmessage(settingsbufftosave.Strings[0]);
SettingsBuffToSave.SaveToFile('bin/settings.txt', Encoding);
end;
当第一条ShowMessage用作代码而不是注释时,它可以工作,而在上面编写的注释函数中,它以与解码相同的方式调用外部异常。
当setingsbufftosave已经调用函数Encode时,它是否可能还没有创建,或者什么?
当时,SettingsBuffer存在并已填充,因此它引发错误似乎很奇怪,只需将ShowMessage放入其中,错误就会消失
(函数Encode基本上是解码的镜像,因此代码在这里并不重要……我想我知道这里发生了什么:我想你的堆栈正在崩溃 此外,我怀疑实际原因是使用未初始化变量的解码过程。ShowMessage语句(如果我是对的,它将是第一个重要语句)更改堆栈上的内容,从而更改未初始化变量 如果我是对的,这将有一些heisenbug属性——您所做的任何事情都将改变未初始化变量的值
有一件事需要尝试:声明一个大的局部变量(其想法是耗尽堆栈空间)并确保编译器不会丢弃它。这将移动内存中的内容,从而可能消除爆炸。如果它起作用,将非常确定正在发生什么。这里的明显问题是代码存在于DLL中。很可能您没有安排DLL共享其主机堆。并且无法向Delphi类传递跨越DLL边界 如果要在模块之间共享Delphi类,必须使用包。当然,另一个选项是将所有代码放在同一个模块中。即删除DLL,并编译可执行文件中的所有内容。最后一个选项是对DLL使用有效的互操作类型 当然,实际错误可能还有其他原因。代码闻起来很难闻。例如,这是什么:
DecodeBuffer:=Buff;
DecodeBuffer
是一个全局变量吗?如果是这样,那么在对象被销毁后您引用该对象似乎是合理的。这并不是说我可以看到任何东西被销毁的证据。您的代码看起来可能有多个问题。作为紧急事项,您需要:
此代码在许多级别上都非常危险。以不安全的方式跨DLL边界使用对象。跨函数调用的对象指针管理不当。您需要重新设计。请尝试以下操作作为开始:
procedure Decode(Buff: PChar; BuffLen: Integer; ListIndex: Integer); stdcall; export;
var
u: integer;
begin
for u := 0 to BuffLen-1 do
begin
Buff^ := DecodeChar(Buff^, (ListIndex mod 5) + 1);
Inc(Buff);
end;
end;
procedure Encode(Buff: PChar; BuffLen: Integer; ListIndex: Integer); stdcall; export;
var
u: integer;
begin
for u := 0 to BuffLen-1 do
begin
Buff^ := EncodeChar(Buff^, (ListIndex mod 5) + 1);
Inc(Buff);
end;
end;
如果我们对解码函数一无所知,就很难帮助您解决这个问题。DLL函数声明是什么?它需要什么参数,返回什么类型?如果没有这些信息,您要求我们猜测可能有什么错误,您可以自己做。解码是什么转身?谁对它返回的内容负责?它是如何销毁的?我想我可能需要发布更多的代码…正如我所说的,我不知道发生了什么以及它在哪里停止..然而,@Ken,Decode函数被声明为外部的,stdcall,期望TStringList并返回完全相同的结果。我在这里的另一个问题中讨论过,它是只是交换字符串列表中每个字符串中的字符。很抱歉,如果看起来我想让你猜,我只是不知道我应该发布多少,因为后面有很多代码,而且,正如前面所说的,如果我在它们之间放一条简单的ShowMessage,效果会很好,什么真的没有任何意义…@SertacAkyuz你的意思是什么“谁对它返回的东西负责”和“它是如何被摧毁的”"?该函数只是声明为外部函数,之后才调用。FromClose事件上的Encode函数也有同样的问题,它基本上有相同的问题;showmessage也能正常工作。我正在用Decode函数更新问题;@just-我的查询涉及通过模块边界的内容,dll是否传递可执行文件字符串或类等,以及如何管理其生存期。否
procedure Decode(Buff: PChar; BuffLen: Integer; ListIndex: Integer); stdcall; external '...';
procedure Encode(Buff: PChar; BuffLen: Integer; ListIndex: Integer); stdcall; external '...';
procedure LoadSettings;
var
h: Integer;
begin
SettingsBuffer := TStringList.Create;
SettingsBuffer.LoadFromFile('bin/settings.txt', TEncoding.ANSI);
for h := 0 to SettingsBuff.Count-1 do
begin
Decode(PChar(SettingsBuff[h]), Length(SettingsBuff[h]), h);
end;
end;
procedure TScribbles.SaveSettings;
var
h: Integer;
begin
for h := 0 to SettingsBuff.Count-1 do
begin
Encode(PChar(SettingsBuff[h]), Length(SettingsBuff[h]), h);
end;
SettingsBuff.SaveToFile('bin/setpb95enc.dll', TEncoding.ANSI);
end;