DLL的代码:
library Encrypt;
uses
  SysUtils,
  Classes,
  output in 'output.pas';
{$R *.res}
function SelectOutString(Source, Key: String;EnAndUn:boolean):string;stdCall;
begin
 if enandun then
  result:=EncryptString(Source,Key)
  else
  result:=UnEncryptString(Source,Key);
end;
exports
 SelectOutString;
begin
end.
调用代码:
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TGetString = function(Source, Key: String;EnAndUn:boolean):string;stdCall;  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    procedure Button1Click(Sender: TObject);  private
    { Private declarations }
  public
    { Public declarations }
  end;var
  Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var LibHandle:THandle;
    SelectOutString:TGetstring;
begin
 try
 libhandle:=loadlibrary('Encrypt.dll');   
 @SelectOutString:=GetProcAddress(libhandle,'SelectOutString');
 if not (@SelectOutString = nil) then
 edit2.Text:=SelectOutString(edit1.Text,'topsoft',true)
 else
 application.MessageBox('出错啦','提示',mb_ok);
 finally
 freelibrary(libhandle);
 end;
end;end.
我跟踪过调用时,可以得出加密的字符,但每次调用完就报地址错误,为什么???

解决方案 »

  1.   

    我也是遇到过这样的问题。
    在调用时很正常可退出程序时执行非法操作出错提示,“runtime error 217 at 00413708", 不解中请高手帮忙.
      

  2.   

    这种问题往往是动态库的资源使用前没创建或使用后没释放造成的,估计你的'output.pas'代码有问题
      

  3.   

    如果DLL的输出函数或过程中存在参数为string或动态数组,那么在调用这个DLL的项目和DLL库项目本身的use子句中都加上Sharemen单元.并且把Borlandmm.dll和Dll一起分发.
    在dll里use sharemem试试.
      

  4.   

    我把另外的代码也写出来,大家看看是哪不对?
    unit output;
    interface
    uses SysUtils,
      Classes;
    function EncryptString(Source, Key: String): String;
    function UnEncryptString(Source, Key: String):string;
    implementationfunction EncryptString(Source, Key: String): String;
    var KeyLen :Integer;
        KeyPos :Integer;
        offset :Integer;
        dest :string;
        SrcPos :Integer;
        SrcAsc :Integer;
        Range :Integer;
    begin
       KeyLen:=Length(Key);
       if KeyLen = 0 then key:='topsoft';
       KeyPos:=0;
       Range:=256;
       Randomize;
       offset:=Random(Range);
       dest:=format('%1.2x',[offset]);
       for SrcPos := 1 to Length(Source) do
          begin
             SrcAsc:=(Ord(Source[SrcPos]) + offset) MOD 255;
             if KeyPos < KeyLen
             then KeyPos:= KeyPos + 1
             else KeyPos:=1;
             SrcAsc:= SrcAsc xor Ord(Key[KeyPos]);
             dest:=dest + format('%1.2x',[SrcAsc]);
             offset:=SrcAsc;
          end;
       Result:=Dest;
    end;function UnEncryptString (Source, Key: String):string;
    var KeyLen :Integer;
        KeyPos :Integer;
        offset :Integer;
        dest :string;
        SrcPos :Integer;
        SrcAsc :Integer;
        TmpSrcAsc :Integer;
    begin
       KeyLen:=Length(Key);
       if KeyLen = 0 then key:='delphi';
       KeyPos:=0;
       offset:=StrToInt('$'+ copy(Source,1,2));
       SrcPos:=3;
       repeat
          SrcAsc:=StrToInt('$'+ copy(Source,SrcPos,2));
          if KeyPos < KeyLen
          Then KeyPos := KeyPos + 1
          else KeyPos := 1;
          TmpSrcAsc := SrcAsc xor Ord(Key[KeyPos]);
          if TmpSrcAsc <= offset
          then TmpSrcAsc := 255 + TmpSrcAsc - offset
          else TmpSrcAsc := TmpSrcAsc - offset;
          dest:=dest + chr(TmpSrcAsc);
          offset:=srcAsc;
          SrcPos:=SrcPos + 2;
       until SrcPos >= Length(Source);
       Result:=Dest;
    end;end.
      

  5.   

    就是没有use ShareMem单元的原因
      

  6.   

    兄弟我前天也做过同类的事情,不过我的程序是把两个窗体放进DLL代码中
    结果在调用过程中,安然无事,可退出时报告地址出错
    原因出在退出时没有释放定义的窗体变量
    我想你的程序退出时也应该把SelectOutString这个变量释放掉
    可能它是自己定义结构变量的因为吧
    我也不知道在你的程序里是否可行
      

  7.   

    我在DLL单元和调用单元中都加了use ShareMem,还是出错?!