DLL文件中的两个接口函数,主要用于加解密操作,函数大致如下:
function encrypt(sYue,sMing:string):pchar;stdcall;
  sMi:string;
  ... ...
  Result := Pchar(sMi);
end;function decrypt(sYue,sMi:string):pchar;stdcall;
  sMing:string;
  ... ...
  decrypt := pchar(sMing);
end;
  下午按lxpbuaa(桂枝香在故国晚秋)朋友所说的,将函数encrypt()和decrypt()的返回类型由string改为pchar,纠正了调用时出现的“Invalid pointer operation”错误,但是在调用decrypt()函数时,会出现返回值错误的情况。
  跟踪时发现:调用decrypt(),当sMing='12'时,返回值为' '(一个空格)???问题就出在这!!!
  如果函数的返回类型为string的话,调用时会出现非法指针的错误提示,但是返回值不会错,这两个函数如果不写成dll调用,嵌入代码中运行又什么问题都没有,一切正常。
  困惑,问题到底出在哪呢???

解决方案 »

  1.   

    《调用decrypt(),当sMing='12'时,返回值为' '(一个空格)???问题就出在这!!!》这里是指函数运行到最后一步,sMing的值为'12'(这个结果是正确的),只是在“decrypt := pChar(sMing)”后,decrypt=' '此值,难道是 pchar()强制转换出错了??
      

  2.   

    我建議你將 sYue,sMi 由String 改為 Pchar
      

  3.   

    你确定在dll中的decrypt()中,sMing='12'嗎??用showmessage顯示正确嗎??
    如果是,那可能你在主程序聲明中漏了 stdcall吧??
    你把主程序調用代碼貼出來,建議采用如下形式:
     function decrypt(sYue,sMi:pchar; pRet:pchar):boolean;stdcall;
    將返回寫在 pRet中!
      

  4.   

    第一个函数encrypt的返回值是否正确呢?
    如果正确, 那第二个函数不应该有问题, 你说呢???
      

  5.   

    在dll中,Result := pchar(sMing);实现的是一个临时转化,也就是说过程返回后,此临时结果已经不存在了。一般的,都是传递返回参数,如:
     function decrypt(sYue,sMi:pchar; pRet:pchar):boolean;stdcall;
    返回值保存在pRet中,调用端需要首先给pRet分配内存。可用:
    GetMem————————————————————————————————————
    宠辱不惊,看庭前花开花落,去留无意;毁誉由人,望天上云卷云舒,聚散任风。
    ————————————————————————————————————
      

  6.   

    我是用dll加载exe运行一步一步调试的,到最后鼠标放在sMing上显示为"sMing='12'",我先试试更改参数类型。
      还有encrypt的返回值在某种情况下也会出错。
      

  7.   

    另附dll全部代码:http://expert.csdn.net/Expert/topic/2273/2273566.xml?temp=8.210391E-02
      

  8.   

    苯死了!!不仅返回值不能用string,参数也不能用string呀,否则一样有内存问题呀
      

  9.   

    另外:由于function decrypt(sYue,sMi:pchar; pRet:pchar):boolean;stdcall;中pRet的长度不能确定,只能确定sYue长度<=16,而sMi的长度不确定,那样在调用时给pRep分配内存? 分配的大小好像不能确定了?
      

  10.   

    看了一下 
    pRep 应分配的length  好像是strlen(sMi) div 2 +1
      

  11.   

    dll的函数或者过程中如果有string类型的,可以在uses中加入sharemem这个类,每个自动生成的dll工程的工程文件的头部都有此说明。不过我还是遇到了返回值的问题,上面的方法有些或者可用,回去试试看
      

  12.   

    to: wanwangzhiwang(万王之王)
    加入sharemem后还是不行,返回值还是有问题。
    现在出错的焦点到是确定在返回值上了。关键是:当调用是sYue,sMing,sMi的字符串位数较多时,出错的几率也少。
    当sYue,sMing都是2位时,先调用encrypt,然后调用decrypt是绝对会出错的。
      

  13.   

    建議如下聲明:function decrypt(sYue,sMi:pchar;var pRet:pchar):boolean;stdcall;
    另外,我比較忙,沒時間看你的代碼,給你的 email;
    我發個例子給你,與你的要求是一樣的,是我以前實現的!!!
      

  14.   

    这个算法的代码是我从vb转换过来的,找了个朋友让他帮忙,直接写成vb的dll。没办法,只怪自己学得太少,所有的都只学了一点毛皮,吸取教训,专心学delphi,以后学习过程中碰到问题,还请大家多多指教。
      谢谢各位了。现将vb的源码和delphi自己整理过的代码附上。
    vb----------------------------------------
    ' PC1 Cipher 128-bit key
    ' (c) Alexander PUKALL 1991
    ' Can be use freely even for commercial applications
    ' Visual Basic 6.0Dim x1a0(9) As Long
    Dim cle(17) As Long
    Dim x1a2 As LongDim inter As Long, res As Long, ax As Long, bx As Long
    Dim cx As Long, dx As Long, si As Long, tmp As Long
    Dim i As Long, c As BytePrivate Sub Assemble()
    x1a0(0) = ((cle(1) * 256) + cle(2)) Mod 65536
    code
    inter = res
    x1a0(1) = x1a0(0) Xor ((cle(3) * 256) + cle(4))
    code
    inter = inter Xor res
    x1a0(2) = x1a0(1) Xor ((cle(5) * 256) + cle(6))
    code
    inter = inter Xor res
    x1a0(3) = x1a0(2) Xor ((cle(7) * 256) + cle(8))
    code
    inter = inter Xor res
    x1a0(4) = x1a0(3) Xor ((cle(9) * 256) + cle(10))
    code
    inter = inter Xor res
    x1a0(5) = x1a0(4) Xor ((cle(11) * 256) + cle(12))
    code
    inter = inter Xor res
    x1a0(6) = x1a0(5) Xor ((cle(13) * 256) + cle(14))
    code
    inter = inter Xor res
    x1a0(7) = x1a0(6) Xor ((cle(15) * 256) + cle(16))
    code
    inter = inter Xor res
    i = 0
    End SubPrivate Sub code()
    dx = (x1a2 + i) Mod 65536
    ax = x1a0(i)
    cx = &H15A
    bx = &H4E35
    tmp = ax
    ax = si
    si = tmp
    tmp = ax
    ax = dx
    dx = tmp
    If (ax <> 0) Then
    ax = (ax * bx) Mod 65536
    End If
    tmp = ax
    ax = cx
    cx = tmp
    If (ax <> 0) Then
    ax = (ax * si) Mod 65536
    cx = (ax + cx) Mod 65536
    End If
    tmp = ax
    ax = si
    si = tmp
    ax = (ax * bx) Mod 65536
    dx = (cx + dx) Mod 65536
    ax = ax + 1
    x1a2 = dx
    x1a0(i) = ax
    res = ax Xor dx
    i = i + 1
    End SubPrivate Sub crypt()
    Form1.Text3 = ""
    si = 0
    x1a2 = 0
    i = 0
    For fois = 1 To 16
    cle(fois) = 0
    Next fois
    champ1 = Form1.Text1
    lngchamp1 = Len(champ1)
    For fois = 1 To lngchamp1
    cle(fois) = Asc(Mid(champ1, fois, 1))
    Next fois
    champ1 = Form1.Text2
    lngchamp1 = Len(champ1)
    For fois = 1 To lngchamp1
    c = Asc(Mid(champ1, fois, 1))
    Assemble
    If inter > 65535 Then
    inter = inter - 65536
    End If
    cfc = (((inter / 256) * 256) - (inter Mod 256)) / 256
    cfd = inter Mod 256
    For compte = 1 To 16
    cle(compte) = cle(compte) Xor c
    Next compte
    c = c Xor (cfc Xor cfd)
    d = (((c / 16) * 16) - (c Mod 16)) / 16
    e = c Mod 16
    Form1.Text3 = Form1.Text3 + Chr$(&H61 + d) ' d+&h61 give one letter range from a to p for the 4 high bits of c
    Form1.Text3 = Form1.Text3 + Chr$(&H61 + e) ' e+&h61 give one letter range from a to p for the 4 low bits of c
    Next fois
    End SubPrivate Sub decrypt()
    Form1.Text2 = ""
    si = 0
    x1a2 = 0
    i = 0
    For fois = 1 To 16
    cle(fois) = 0
    Next fois
    champ1 = Form1.Text1
    lngchamp1 = Len(champ1)
    For fois = 1 To lngchamp1
    cle(fois) = Asc(Mid(champ1, fois, 1))
    Next fois
    champ1 = Form1.Text3
    lngchamp1 = Len(champ1)
    For fois = 1 To lngchamp1
    d = Asc(Mid(champ1, fois, 1))
    If (d - &H61) >= 0 Then
    d = d - &H61  ' to transform the letter to the 4 high bits of c
    If (d >= 0) And (d <= 15) Then
    d = d * 16
    End If
    End If
    If (fois <> lngchamp1) Then
    fois = fois + 1
    End If
    e = Asc(Mid(champ1, fois, 1))
    If (e - &H61) >= 0 Then
    e = e - &H61 ' to transform the letter to the 4 low bits of c
    If (e >= 0) And (e <= 15) Then
    c = d + e
    End If
    End If
    Assemble
    If inter > 65535 Then
    inter = inter - 65536
    End If
    cfc = (((inter / 256) * 256) - (inter Mod 256)) / 256
    cfd = inter Mod 256
    c = c Xor (cfc Xor cfd)
    For compte = 1 To 16
    cle(compte) = cle(compte) Xor c
    Next compte
    Form1.Text2 = Form1.Text2 + Chr$(c)
    Next fois
    End SubPrivate Sub Command1_Click()
    If Len(Form1.Text1) > 16 Then
    MsgBox ("The password must be <=16 characters")
    Else
    If Len(Form1.Text1) > 0 Then
    crypt
    End If
    End If
    End Sub
      

  15.   

    Delphi--------------------------------------------
    var
      Form1: TForm1;  x1a0:array[0..7] of longint;
      cle:array[1..16] of longint;
      x1a2:longint;  inter,res,ax,bx,cx,dx,si,tmp:longint;
      i:longint;
      c:Byte;implementation{$R *.dfm}function TForm1.GetAsc(var str:string):integer;
    var
      cTmp:char;
      bRen:integer;
    begin
      cTmp := str[1];
      bRen := ord(cTmp);
      GetAsc := bRen;
    end;function Tform1.crypt(var sYue,sMing:string):string;
    var
      fois,compte:integer;
      champ1:string;
      lngchamp1:integer;
      d,e:integer;
      stmp:string;
      cfc,cfd:integer;
      sMi:string;
    begin
      stmp := '';
      sMi := '';
      si := 0;
      x1a2 := 0;
      i := 0;  For fois := 1 To 16 do
        cle[fois] := 0;  champ1 := sYue;
      lngchamp1 := Length(champ1);  For fois := 1 To lngchamp1 do
      begin
        stmp := MidStr(champ1, fois, 1);
        cle[fois] := GetAsc(stmp);
      end;  champ1 := sMing;
      lngchamp1 := Length(champ1);
      For fois := 1 To lngchamp1 do
      begin
        stmp := MidStr(champ1, fois, 1);
        c := GetAsc(stmp);    Assemble();    If inter > 65535 Then
          inter := inter - 65536;    cfc := Round((((inter / 256) * 256) - (inter Mod 256)) / 256);
        cfd := inter Mod 256;    For compte := 1 To 16 do
          cle[compte] := cle[compte] Xor c;    c := c Xor (cfc Xor cfd);    d := Round((((c / 16) * 16) - (c Mod 16)) / 16);
        e := c Mod 16;    sMi := sMi + Chr(97 + d);
        sMi := sMi + Chr(97 + e);
      end;
      crypt := sMi;
    end;function Tform1.decrypt(var sYue,sMi:string):string;
    var
      fois,compte:integer;
      champ1:string;
      lngchamp1:integer;
      d,e:integer;
      stmp:string;
      cfc,cfd:integer;
      sMing:string;
    begin
      sMing  := '';
      si := 0;
      x1a2 := 0;
      i := 0;  For fois := 1 To 16 do
        cle[fois] := 0;
      champ1 := sYue;
      lngchamp1 := Length(champ1);  For fois := 1 To lngchamp1 do
      begin
        stmp := MidStr(champ1, fois, 1);
        cle[fois] := GetAsc(stmp);
      end;  champ1 := sMi;
      lngchamp1 := Length(champ1);  fois :=1;
      while fois<= lngchamp1 do
      begin
        stmp := MidStr(champ1, fois, 1);
        d := GetAsc(stmp);
        If (d - 97) >= 0 Then
        begin
          d := d - 97;
          If (d >= 0) And (d <= 15) Then
            d := d * 16;
        end;    If (fois <> lngchamp1) Then
          fois := fois + 1;    stmp := MidStr(champ1, fois, 1);
        e := GetAsc(stmp);
        If (e - 97) >= 0 Then
        begin
          e := e - 97;
          If (e >= 0) And (e <= 15) Then
            c := d + e;
        end;    Assemble();    If inter > 65535 Then
          inter := inter - 65536;    cfc := Round((((inter / 256) * 256) - (inter Mod 256)) / 256);
        cfd := inter Mod 256;    c := c Xor (cfc Xor cfd);    For compte := 1 To 16 do
          cle[compte] := cle[compte] Xor c;    sMing  := sMing + Chr(c);
        fois := fois+1;
      end;
      decrypt := sMing;
    end;procedure Tform1.ccode();
    begin
      dx := (x1a2 + i) Mod 65536;
      ax := x1a0[i];
      cx := 346;
      bx := 20021;  tmp := ax;
      ax := si;
      si := tmp;  tmp := ax;
      ax := dx;
      dx := tmp;  If (ax <> 0) Then
        ax := (ax * bx) Mod 65536;  tmp := ax;
      ax := cx;
      cx := tmp;  If (ax <> 0) Then
      begin
        ax := (ax * si) Mod 65536;
        cx := (ax + cx) Mod 65536;
      end;  tmp := ax;
      ax := si;
      si := tmp;
      ax := (ax * bx) Mod 65536;
      dx := (cx + dx) Mod 65536;  ax := ax + 1;  x1a2 := dx;
      x1a0[i] := ax;  res := ax Xor dx;
      i := i + 1;
    end;procedure Tform1.assemble();
    begin
      x1a0[0] := ((cle[1] * 256) + cle[2]) Mod 65536;
      ccode();
      inter := res;  x1a0[1] := x1a0[0] Xor ((cle[3] * 256) + cle[4]);
      ccode();
      inter := inter Xor res;;  x1a0[2] := x1a0[1] Xor ((cle[5] * 256) + cle[6]);
      ccode();
      inter := inter Xor res;;  x1a0[3] := x1a0[2] Xor ((cle[7] * 256) + cle[8]);
      ccode();
      inter := inter Xor res;;  x1a0[4] := x1a0[3] Xor ((cle[9] * 256) + cle[10]);
      ccode();
      inter := inter Xor res;  x1a0[5] := x1a0[4] Xor ((cle[11] * 256) + cle[12]);
      ccode();
      inter := inter Xor res;  x1a0[6] := x1a0[5] Xor ((cle[13] * 256) + cle[14]);
      ccode();
      inter := inter Xor res;  x1a0[7] := x1a0[6] Xor ((cle[15] * 256) + cle[16]);
      ccode();
      inter := inter Xor res;  i := 0;
    end;结贴,谢谢各位。