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());
}