Delphi 7:函数在dll中调用时崩溃,在exe中工作

Zer*_*y99 2 delphi crash dll pascal function

我在网上找到了Delphi 7字符串解码器功能("Decrypt")的问题.它需要一个字符串和1到120之间的四个数值来解码它.将该函数放在可执行文件中并运行它可以很好地工作.但是,我想在DLL中运行它.我正在使用额外的函数从调用任务接收必要的值,并从那里调用解密函数.出于某种原因,我无法将手指放在上面,每次dll调用解密函数时,主机应用程序都会崩溃.在过去的几个小时里,我一直在尝试一切可以让它发挥作用,但没有成功.我是Delphi和Pascal的新手,所以我可能只是忽略了一些明显的东西.无论哪种方式,我都输了.任何帮助将不胜感激.

编辑:这是崩溃时弹出的Windows错误:

  Fault Module Name:    StackHash_0a9e
  Fault Module Version: 0.0.0.0
  Fault Module Timestamp:   00000000
  Exception Code:   c0000005
  Exception Offset: 00000000
  OS Version:   6.1.7600.2.0.0.256.1
  Locale ID:    1031
  Additional Information 1: 0a9e
  Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
  Additional Information 3: 0a9e
  Additional Information 4: 0a9e372d3b4ad19135b953a78882e789
Run Code Online (Sandbox Code Playgroud)

这是我使用的代码:

library decrypt_test_dll;

uses
  SysUtils,
  Classes,
  Dialogs;

{$R *.res}

function callfunction(externalstring, value1, value2, value3, value4: PAnsiChar):integer; cdecl;
var
  convkey1, convkey2, convkey3, convkey4 : string;
  convstring, decodedstring : string;
  Decrypt : function(Text : string; Key1, Key2, Key3, Key4 : Integer) : string;
begin
  convkey1 := value1;
  convkey2 := value2;
  convkey3 := value3;
  convkey4 := value4;
  convstring := externalstring;
  decodedstring := Decrypt(externalstring, strtoint(convkey1), strtoint(convkey2), strtoint(convkey3), strtoint(convkey4));
  showmessage(decodedstring);
end;

function Decrypt(Text : string; Key1, Key2, Key3, Key4 : Integer) : string;
var
 BufS, Hexa1, Hexa2 : string;
  BufI, BufI2, Divzr, Sc, Sl, Num1, Num2, Num3, Num4, Res1, Res2, Res3, Res4 : Integer;
begin
  showmessage('within decryption function');
 Sl := Length(Text);
  Sc := 0;
  BufS := '';
  if (Key1 in [1 .. 120]) and (Key2 in [1 .. 120]) and (Key3 in [1 .. 120]) and (Key4 in [1 .. 120]) then
    begin
      Divzr := Key1 * Key4;
      BufI2 := Key3 * Key2;
      Divzr := Divzr - BufI2;
      if Divzr = 0 then
        begin
          Result := '';
          Exit;
        end;
    end
  else
    begin
      Result := '';
      Exit;
    end;
  repeat
    for BufI := 1 to 4 do
      begin
        Inc(Sc);
        Hexa1 := IntToHex(Ord(Text[Sc]), 2);
        Inc(Sc);
        Hexa2 := IntToHex(Ord(Text[Sc]), 2);
        if Hexa1 = 'FF' then
          begin
            Hexa1 := '00';
            Hexa2 := '00';
          end;
        if Hexa1 = 'FE' then Hexa1 := '00';
        if Hexa1 = 'FD' then
          begin
            Hexa1 := Hexa2;
            Hexa2 := '00';
          end;
        case BufI of
          1 : Res1 := StrToInt('$' + Hexa1 + Hexa2);
          2 : Res2 := StrToInt('$' + Hexa1 + Hexa2);
          3 : Res3 := StrToInt('$' + Hexa1 + Hexa2);
          4 : Res4 := StrToInt('$' + Hexa1 + Hexa2);
        end;
      end;
    BufI := Res1 * Key4;
    BufI2 := Res2 * Key3;
    Num1 := BufI - BufI2;
    Num1 := Num1 div Divzr;
    BufI := Res2 * Key1;
    BufI2 := Res1 * Key2;
    Num2 := BufI - BufI2;
    Num2 := Num2 div Divzr;
    BufI := Res3 * Key4;
    BufI2 := Res4 * Key3;
    Num3 := BufI - BufI2;
    Num3 := Num3 div Divzr;
    BufI := Res4 * Key1;
    BufI2 := Res3 * Key2;
    Num4 := BufI - BufI2;
    Num4 := Num4 div Divzr;
    BufS := BufS + Chr(Num1) + Chr(Num2) + Chr(Num3) + Chr(Num4);
    until Sc >= Sl;
    Result := BufS;
end;

exports
  Decrypt index 1,
  callfunction index 2;

begin
end.
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 5

这段代码都错了:

function callfunction(externalstring, value1, value2, value3, value4: PAnsiChar):integer; cdecl;
var
  convkey1, convkey2, convkey3, convkey4 : string;
  convstring, decodedstring : string;
  Decrypt : function(Text : string; Key1, Key2, Key3, Key4 : Integer) : string;
begin
  convkey1 := value1;
  convkey2 := value2;
  convkey3 := value3;
  convkey4 := value4;
  convstring := externalstring;
  decodedstring := Decrypt(externalstring, strtoint(convkey1), strtoint(convkey2), strtoint(convkey3), strtoint(convkey4));
  showmessage(decodedstring);
end;
Run Code Online (Sandbox Code Playgroud)

Decrypt永远不会分配局部变量.所以当你打电话时Decrypt,一切都会发生.您需要移动callfunction到单元的底部,以便它显示在真实之后Decrypt.并且您需要删除函数指针变量.

function callfunction(externalstring, value1, value2, value3, value4: PAnsiChar):integer; cdecl;
var
  convkey1, convkey2, convkey3, convkey4 : string;
  convstring, decodedstring : string;
begin
  convkey1 := value1;
  convkey2 := value2;
  convkey3 := value3;
  convkey4 := value4;
  convstring := externalstring;
  decodedstring := Decrypt(externalstring, strtoint(convkey1), strtoint(convkey2), strtoint(convkey3), strtoint(convkey4));
  showmessage(decodedstring);
end;
Run Code Online (Sandbox Code Playgroud)

您也不应该string在导出的DLL函数中用作参数(或实际上是返回值).它不是interop的有效类型,因为它依赖于使用相同string实现的接口的两侧以及相同的内存管理器.Decrypt如果要导出界面,则需要找到另一种定义界面的方法.或者您可能根本不应该导出该功能.我无法确切地知道.我的猜测是你实际上是在调用callfunction而不是Decrypt从调用代码调用.无论如何,在当前状态下,您不得出口Decrypt.

还有一点要做.当您提出涉及模块界面的问题时,应始终显示界面的两侧.这里显示了DLL,但没有显示调用DLL的代码.错误可能在那里.实际上,除了我指出的错误之外,还有一个错误.