1

我有一个这样的函数声明:

function execProc(ProcName,InValues:PChar;out OutValues:PChar):integer; //The "OutValues" is a out parameter.

我这样称呼这个函数:

procedure TForm1.Button6Click(Sender: TObject);
var
 v:integer;
 s:pchar;
begin
 Memo1.Clear;
 v := execProc(pchar('PROC_TEST'),pchar('aaa'),s);
 showmessage(inttostr(v)); //mark line
 Memo1.Lines.Add(strpas(s));
end;

当我删除标记行(showmessage(inttostr(v)))时,我将在Memo1中显示正确的结果,但如果我继续使用showmessage(),memo1将显示错误字符串:“Messag”,为什么? 谢谢你的帮助!

function execProc(ProcName,InValues:PChar;out OutValues:PChar):integer;
var
  str: TStrings;
  InValue,OutValue: string;
  i,j,scount: integer;
begin
Result := -100;
i := 0;
j := 0;
str := TStringList.Create;
try
  sCount := ExtractStrings(['|'], [], InValues, str);
  with kbmMWClientStoredProc1 do
  begin
    Close;
    Params.Clear;
    StoredProcName := StrPas(ProcName);
    FieldDefs.Updated := False;
    FieldDefs.Update;
    for i := 0 to Params.Count - 1 do
    begin
      if (Params[i].ParamType = ptUnknown) or
       (Params[i].ParamType = ptInput) or
       (Params[i].ParamType = ptInputOutput) then
      begin
        inc(j);
        InValue := str[j-1];
        Params[i].Value := InValue;
      end;
    end;
    try
      ExecProc;
      for i := 0 to Params.Count - 1 do
      begin
        if  (Params[i].ParamType = ptOutput) or
       (Params[i].ParamType = ptInputOutput) then
         OutValue := OutValue + '|' + Params[i].AsString;
      end;
      OutValues := PChar(Copy(OutValue,2,Length(OutValue)-1));
      Result := 0;
    except
      on E:Exception do
      begin
        if E.Message = 'Connection lost.' then Result := -101;//服务器连接失败
        if E.Message = 'Authorization failed.' then Result := -102;//身份验证失败
        Writelog(E.Message);
      end;
    end;
  end;
finally
  str.Free;
end;
end;
4

1 回答 1

2

问题在于界面的设计和PChar.

OutValues := PChar(Copy(OutValue,2,Length(OutValue)-1));

这是通过创建一个隐含的、隐藏的、本地的字符串变量来实现的,该变量保存该值

Copy(OutValue,2,Length(OutValue)-1)

当函数返回时,该字符串变量被销毁,因此OutValues指向已释放的内存。有时您的程序似乎可以工作,但这完全取决于机会。正如您所观察到的,任何微小的变化都会扰乱这一点。

这个问题很容易解决。只需使用字符串参数而不是PChar. 这将使代码更易于阅读并使其正常工作。

function execProc(ProcName, InValues: string; out OutValues: string): integer;
于 2012-05-21T06:12:38.860 回答