我怎么也找不到原因就一个很简单的程序,网上的一个MD5加密单元我把他做成了DLL再用EXE调用他就报错:Invalid point operation我已经把它上传到网上,有哪位朋友可以帮我看看啊!
下载地址

解决方案 »

  1.   

    1、在DLL中最好不要直接返回String;
    2、向DLL中传递参数的时候最好不要直接传递String类型参数。
    ----------------------------最好的解决方法:
    DLL:function RivestStr(const AParam: PAnsiChar; AResult: PAnsiChar): Integer; StdCall;
    var
      s1, s2: String;
    begin
      s1 := StrPas(AParam);
      s2 := MD5Print(MD5String(s1));
      Result := Length(s2) + 1;
      if Assigned(AResult) then
        StrPCopy(AResult, s2);
    end;EXE:function doMD5String(s: String): String;implementationfunction RivestStr(const AParam: PAnsiChar; AResult: PAnsiChar): Integer; StdCall; External 'md5dll.dll';function doMD5String(s: String): String;
    var
      i: Integer;
      p: PAnsiChar;
    begin
      i := RivestStr(PAnsiChar(s), p);
      GetMem(p, i);
      try
        RivestStr(PAnsiChar(s), p);
        Result := StrPas(p);
      finally
        FreeMem(p);
      end;
    end;//RivestFile函数也做类似处理
    end;
      

  2.   

    Invalid point operation无效的指针操作,譬如A: string没有初始化(A := '';),就对A[1]赋值或A := B等操作
      

  3.   

    exe文件implementation
    function RivestStr(Str: pchar):pchar; stdcall; external 'md5dll.dll';
    function RivestFile(FileName: pchar):pchar; stdcall; external 'md5dll.dll';
    {$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    begin
      edit1.Text:=RivestStr(pchar(edit1.Text));
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      edit1.Text:=RivestFile('C:\WINDOWS\explorer.exe');
    end;
      

  4.   

    dll文件,已经测试好用function MD5String(M: pchar): MD5Digest; stdcall;
    function MD5File(N: pchar): MD5Digest; stdcall;
    function MD5Print(D: MD5Digest): pchar; stdcall;
    function MD5Match(D1, D2: MD5Digest): Boolean; stdcall;
    function RivestStr(Str: pchar): pchar; stdcall;        //字符串MD5加密结果是32位大写的
    function RivestFile(FileName: pchar): pchar; stdcall;  //对文件MD5加密结果是32位大写的
    ...
    implementation
    ...
    // Create digest of given Message
    function MD5String(M: pchar): MD5Digest; stdcall;
    var
      Context: MD5Context;
    begin
      MD5Init(Context);
      MD5Update(Context, pChar(M), Length(M));
      MD5Final(Context, result);
    end;// Create digest of file with given Name
    function MD5File(N: pchar): MD5Digest; stdcall;
    var
      FileHandle: THandle;
      MapHandle: THandle;
      ViewPointer: pointer;
      Context: MD5Context;
    begin
      MD5Init(Context);
      FileHandle := CreateFile(pChar(N), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
        nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
      if FileHandle <> INVALID_HANDLE_VALUE then try
        MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
        if MapHandle <> 0 then try
          ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0);
          if ViewPointer <> nil then try
            MD5Update(Context, ViewPointer, GetFileSize(FileHandle, nil));
          finally
            UnmapViewOfFile(ViewPointer);
          end;
        finally
          CloseHandle(MapHandle);
        end;
      finally
        CloseHandle(FileHandle);
      end;
      MD5Final(Context, result);
    end;function MD5Print(D: MD5Digest): pchar; stdcall;
    var
      I: Byte;
      tmp:string;
    const
      Digits: array[0..15] of Char =
      ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
    begin
      tmp := '';
      for I := 0 to 15 do
        tmp := tmp + Digits[(D[I] shr 4) and $0F] + Digits[D[I] and $0F];
      result:=pchar(tmp);  
    end;// Compare two Digests
    function MD5Match(D1, D2: MD5Digest): Boolean; stdcall;
    var
      I: Byte;
    begin
      I := 0;
      result := True;
      while result and (I < 16) do
      begin
        result := D1[I] = D2[I];
        Inc(I);
      end;
    end;function RivestStr(Str: pchar): pchar; stdcall;
    begin
      result := MD5Print(MD5String(Str));
    end;function RivestFile(FileName: pchar): pchar; stdcall;
    begin
      result := MD5Print(MD5File(FileName));
    end;
      

  5.   

    支持1楼的方法.楼上的代码不知道测试了没有,可能会有问题.
    建议楼主仔细看下Delphi帮助对AnsiString(string)的那段文字描述.String其实由一个内存管理器根据引用计数来管理其内存释放与否.它从堆中分配.不同于PChar,它有4个字节的长度和4个字节的引用计数.
    Invalid point operation好象是栈和堆的内存指针混指了会报的错。
      

  6.   

    你们可以把改过的地方加个注释再把它发我邮箱吗?[email protected] 最好少改点!改多了我就糊涂了,你们这么多的方法我都有点糊涂了,我在大富翁上也问过了,它上面说的方法我试试也没有用,你们的方法我都不知道怎么弄,谢谢!!!!!!!!!!!!!!!!!!我可以想办法再给你们加点分的。