将一段加密函数做成dll,但是出现返回的加密串 有时 不能被主程序获取的情况
dll中的加密函数:
function jiami(strN :PChar;strInput: PChar): PChar;stdcall;
Var
  test:string;
  ……
Begin
  //编码加密等操作,此过程用的是string,而不是pchar,将加密得到的string赋给test。具体过程繁琐,略。
  result := PChar(test);//将结果用pchar返回。断点跟踪发现result一直是有结果的(正确),我想问题出在dll跟主程序之间传pchar时。
End;调用函数:FH:=loadlibrary(pchar(ExtractFilePath(Application.Exename)+'dll1.dll'));
  if FH<>0 then
    MyFun:=GetProcAddress(FH,'jiami');
  try
    Edit5.Text :=  MyFun(PChar(Edit4.Text),PChar(Edit5.Text));
  finally
    FreeLibrary(FH);
  end;请大家帮忙,问题怎么解决?(确定经跟踪发现dll的result一直是有结果的)

解决方案 »

  1.   

    这样试试 
    function jiami(strN, strInput, strOutput: PChar): Integer;stdcall;由调用者开辟缓冲区
      

  2.   

    zhangl_cn(和尚-修行) 的是正解function jiami(strN, strInput, strBuf: PChar; BufSize: Integer): Integer;stdcall;最好由调用者传入缓冲区大小
      

  3.   

    谢谢,
    看来我需要修改dll的函数了,
    function jiami(strN, strInput, strBuf: PChar; BufSize: Integer): Integer;stdcall;
    在主程序中怎么调用啊?“缓冲区”对我有点高深^_^,strBuf: 是缓冲区吧?那么 BufSize就是缓冲区长度了?需要定义一个值?如果加密出来的长度不定怎么办?
      

  4.   

    应该是因为string变量在函数结束后被销毁了,所以返回给主程序的指针已经实效,即决办法就是由主程序开辟缓冲区,或者试试在函数里先用getmem开辟一段缓冲区,但不对其进行释放,返回到主程序里之后,使用结束再释放掉.这样可以避免缓冲区溢出,但需要注意缓冲区的销毁工作.
      

  5.   

    var
      strBuf: PChar;
      BufSize: Integer;
    begin
      BufSize := 1024;
      strBuf := AllocMem(BufSize);
      jiami(strN, strInput, strBuf, BufSize);
      ShowMessage(strBuf);
      FreeMem(strBuf);
    end;
      

  6.   

    function jiami(strN, strInput, strBuf: PChar; BufSize: Integer): Integer;stdcall;
    var
      s: string;
      len: integer;
    begin
      //说明下,strBuf就是缓冲区的内存指针
      s := 计算加密串;
      if (Length(s) > BufSize - 1) then  //如果缓冲区不够s的长度,返回-1表明白函数调用失败
        result := -1
      else   //如果缓冲区够,将内容复制到缓冲区,并返实际写入缓冲的字节数
      begin
        result := Length(s);
        Move(string[1], strBuf^, Length(s));
      end;
    end;
      

  7.   

    谢谢zwjchina(蒲石),好用。
    帖子留着,攒多分再给大家,特别是zwjchina。
    另指点小bug:Move(string[1], strBuf^, Length(s));这句编译不通过,改成Move(s[1], strBuf^, Length(s));就好了,不知对否?
      

  8.   

    有这样的问题  加密后字符串中有可能出现NULL符
    但是字符串遇到NULL符 读取时中止所以在你转换完成时,要对你的字符串地址空间遍历一下   找一个不用的特殊字符替换NULL符