Delphi方法签名转换为c#

本文关键字:转换 方法 Delphi | 更新日期: 2023-09-27 17:57:32

我在调用的Delphi2007函数中有这个签名(SomeOtherFile是它调用的另一个DLL):

function MyFunction(Place, Name: PChar):_Recordset; stdcall; far; external 'SomeOtherFile.DLL';

我试着用C#代码这样称呼它:

[DllImport("MyFile.dll", CallingConvention = CallingConvention.StdCall,
    CharSet = CharSet.Ansi, EntryPoint="MyFunction")]
public static extern DataSet MyFunction(string Place, [MarshalAs(UnmanagedType.LPStr)]string Name);

每当我运行这个并将其存储到变量中时,我都会收到一个关于类型不匹配的运行时错误。我想我读错了签名,但我不知道它应该是什么。

编辑实际错误是:对PInvoke函数[…]的调用使堆栈不平衡。。。我还尝试过使用MarshalAs属性的两个param,它抛出了相同的东西。

Delphi方法签名转换为c#

我已经做了一些挖掘,我认为您需要将返回值封送为Recordset接口。我确信P/InvokeMarshaller不会神奇地将Delphi _Recordset转换为.net DataSet类实例。

所以我认为你可以这样写:

[DllImport("MyFile.dll")]
[return: MarshalAs(UnmanagedType.Interface)]
public static extern object MyFunction(string Place, string Name);

像这样称呼

Recordset rs = (Recordset) MyFunction(Place, Name);

我假设PlaceName参数是输入参数,在这种情况下,字符串的默认编组很好。

您不需要指定ANSI字符集,因为这也是默认值。如果入口点的名称与C#函数的名称相同,则无需命名该入口点。您不需要指定调用约定,因为stdcall是默认约定。

Recordset接口位于ADODB命名空间中。

顺便说一句,在Delphi函数导入中使用far是伪造的。一旦我们抛弃了16位的世界,far关键字就不再有任何作用。