Delphi-程序未能完成,但使用“可正常工作”;showmessage";之间

Delphi-程序未能完成,但使用“可正常工作”;showmessage";之间,delphi,Delphi,我甚至不知道该怎么问这个问题,因为我不知道它是否与执行时间、应用程序进程、消息过程或其他任何事情有关 我(对我来说)遇到了一些奇怪的情况,程序无法运行并在运行时引发系统异常,而如果我将“showmessage”放在中间(这样我就可以很快看到中间发生了什么。不知何故,我更喜欢这种方式而不是手表…) 我不确定代码是否重要,但我将在下面给出: procedure LoadSettings; var SettingsBuffToLoad: TStringList; begin SettingsBuf

我甚至不知道该怎么问这个问题,因为我不知道它是否与执行时间、应用程序进程、消息过程或其他任何事情有关

我(对我来说)遇到了一些奇怪的情况,程序无法运行并在运行时引发系统异常,而如果我将“showmessage”放在中间(这样我就可以很快看到中间发生了什么。不知何故,我更喜欢这种方式而不是手表…)

我不确定代码是否重要,但我将在下面给出:

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问题
  • 删除全局变量
  • 修复生命周期问题。停止泄漏
  • 启用范围检查以定位缓冲区溢出
  • 在调试模式下添加FastMM以尝试捕获堆损坏

  • 此代码在许多级别上都非常危险。以不安全的方式跨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;