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

时间:2012-04-21 19:48:21

标签: delphi function dll crash pascal

我遇到了在线发现的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

这是我使用的代码:

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.

2 个答案:

答案 0 :(得分: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;

永远不会分配局部变量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;

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

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

答案 1 :(得分:0)

如果字符串操作代码如exe中所示但不是来自DLL,则检查DLL是否具有delphi内存管理器,因为FIRST使用项目。

uses
  ShareMem

这在Dephi exe中是隐含的,但不在其DLL中。

这总是Delphi 6 DLL和字符串最喜欢的问题,不能说它是否仍然适用于Delphi 7!