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