Delphi的dll如何向C#传出string(2)

delphi xe开发的dll有Test_ReturnPChar和Test_ReturnPAnsiChar两个函数:

procedure MoveStr2PChar(const AStr:WideString;const APChar:PWideChar;var APCharLen:integer);
var
  oldLen:integer;
  sLen:integer;
begin
  oldLen:=APCharLen;
  sLen:=Length(AStr);
  if APCharLen<sLen+1 then
  begin
    //要求长度加上最后的#0
    APCharLen:=sLen+1;
    Raise Exception.CreateFmt(S_ParamSizeNotEnough,['APChar',InttoStr(oldLen),InttoStr(sLen+1)]);
  end;
  //返回字符数,包含最后#0
  APCharLen:=sLen+1;
  Move(AStr[1],APChar^,sLen*2);
  //写入最后的#0
  PWideChar(Integer(APChar)+sLen*2)^:=#0;
end;

procedure MoveAnsiStr2PAnsiChar(const AStr:AnsiString;const APChar:PAnsiChar;var APCharLen:integer);
var
  oldLen:integer;
  sLen:integer;
begin
  oldLen:=APCharLen;
  sLen:=Length(AStr);
  if APCharLen<sLen+1 then
  begin
    //要求长度加上最后的#0
    APCharLen:=sLen+1;
    Raise Exception.CreateFmt(S_ParamSizeNotEnough,['APChar',InttoStr(oldLen),InttoStr(sLen+1)]);
  end;
  //返回字符数,包含最后#0
  APCharLen:=sLen+1;
  Move(AStr[1],APChar^,sLen);
  //写入最后的#0
  PAnsiChar(Integer(APChar)+sLen)^:=#0;
end;

function Test_ReturnPChar(const APChar:PWideChar;var APCharLen:integer):HResult;
var
  ws:WideString;
begin
  Result:=0;
  try
    ws:='Software Co.,Ltd.';
    MoveStr2PChar(ws,APChar,APCharLen);
  except
    on E:Exception do
    begin
      Result:=1000;
      g_LastErrorMsg:=E.Message;
    end;
  end;
end;

function Test_ReturnPAnsiChar(const APChar:PAnsiChar;var APCharLen:integer):HResult;
var
  s:AnsiString;
begin
  Result:=0;
  try
    s:='Software Co.,Ltd.';
    MoveAnsiStr2PAnsiChar(s,APChar,APCharLen);
  except
    on E:Exception do
    begin
      Result:=1000;
      g_LastErrorMsg:=E.Message;
    end;
  end;
end;

即,传递进去一个PWideChar/PAnsiChar,函数会修改其字符串。

在c#,因为string都是unicode,PWideChar可以直接用string处理,也可以用StringBuilder处理;但PAnsiChar只能用StringBuilder处理:

[DllImport("Stub.dll", EntryPoint = "Test_ReturnPChar", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int Test_ReturnPChar([MarshalAs(UnmanagedType.LPWStr)]string APChar, 
    ref int APCharLen);

[DllImport("Stub.dll", EntryPoint = "Test_ReturnPAnsiChar", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int Test_ReturnPAnsiChar([MarshalAs(UnmanagedType.LPStr)]StringBuilder APChar,
    ref int APCharLen);

private void button1_Click(object sender, EventArgs e)
{
    
    int len=1000;
    string s=new string((char)0,len);
    yjDllImport_TMTS.Test_ReturnPChar(s, ref len);
    MessageBox.Show(s);

    len = 1000;
    //string s2 = new string((char)0, l);
    StringBuilder sb = new StringBuilder(len);
    yjDllImport_TMTS.Test_ReturnPAnsiChar(sb, ref len);
    MessageBox.Show(sb.ToString());
}
原创文章 159 获赞 11 访问量 36万+

猜你喜欢

转载自blog.csdn.net/acrodelphi/article/details/8963758