调用Delphi dll函数时的PInvokeStackImbalance
本文关键字:PInvokeStackImbalance 函数 Delphi dll 调用 | 更新日期: 2023-09-27 18:24:32
(非COM)Delphi dll有一个正在导出的函数:
function GetQuestions(Digit1, Digit2: string; CountryISO: string):string;
我已将此dll添加为Visual Studio 2012中的现有项,并将其"生成操作"设置为"无",将"复制到输出目录"设置为始终复制。
包含DllImportAttribute
:的类
public class RefundLibrary
{
[DllImport("RefundLibrary.dll", EntryPoint = "GetQuestions",
CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr GetQuestions(string digit1, string digit2,
string countryISO);
}
当我在WebForm的Page_Load
中调用此方法时(不确定是否相关),它会在下面指示的行上抛出一个可能的签名不匹配的PInvokeStackImbalance
:
protected void Page_Load(object sender, EventArgs e)
{
IntPtr str = RefundLibrary.GetQuestions("", "", "BE"); //<- here
string result = Marshal.PtrToStringUni(str);
testp.InnerText = result;
}
我还尝试将DllImport方法的返回类型更改为字符串,错误完全相同。
我认为就Embarcadero文档而言,Marshal.PtrToStringUni(str)
是正确的?
在RAD Studio中,字符串是UnicodeString 的别名
这真的是签名不匹配吗?我缺少什么(显然,除了对P/Invoke有一个不错的理解)?
您不能调用该函数。它使用仅Delphi的register
调用约定,并使用Delphi字符串。更改为:
procedure GetQuestions(
Digit1: WideString;
Digit2: WideString;
CountryISO: WideString;
out Questions: WideString
); stdcall;
在C#侧:
[DllImport("RefundLibrary.dll")]
public static extern void GetQuestions(
[MarshalAs(UnmanagedType.BStr)]
string digit1,
[MarshalAs(UnmanagedType.BStr)]
string digit2,
[MarshalAs(UnmanagedType.BStr)]
string countryISO,
[MarshalAs(UnmanagedType.BStr)]
out string questions
);
WideString/BStr
的使用对于out参数来说是非常好的。因为内容是在共享COM堆上分配的,这意味着调用者可以解除分配。
您可以使用PWideChar/LPWStr
作为输入参数。那会很好的。我使用WideString
是因为我想保持一致。这取决于你。