2011-05-23 28 views
1

我有我打电话德尔福2007功能此签名(该SomeOtherFile是,它依次调用另一个DLL):我想叫它德尔菲法签名转换成C#

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的函数调用[...]已不平衡堆栈...我也尝试都PARAMS使用MarshalAs特性,并且它抛出同样的事情。

+0

“类型不匹配”通常是编译时错误,而不是运行时错误。您能否引用错误文本并告诉我们您得到的错误的类名?另外,是什么让你认为第二个参数需要特别编组,但第一个不需要? “MyFunction”对这些指针有什么作用? (它写入缓冲区,还是只读取它们?)最后,什么是DataSet和_Recordset? – 2011-05-23 18:13:56

+0

很难看到P/Invoke编组匹配'_Recordset'和'DataSet'!你也不需要'MarshalAs'属性,但这是一个细微之处。 – 2011-05-23 18:18:44

+0

@Dan为什么你在'Name'参数中使用'MarshalAs'而不是在'Place'中,如果两个参数都是相同的类型? – RRUZ 2011-05-23 18:49:04

回答

0

我已经做了一些挖掘,我认为你需要将返回值编组为Recordset接口。我确定P/Invoke编组器不会奇迹般地将你的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关键字就停止了。

+0

谢谢大卫的帮助(还有RRUZ),但我也遇到了同样的错误。如果有帮助,下面是有人用Delphi写的代码:Recordset:= MyFunction('Home',PChar('Steve'));那第二个参数让我觉得我的签名是错误的。 – Dan 2011-05-24 13:08:46

+0

该函数的参数将会很好。我相信P/Invoke的一部分很好。这个问题肯定是RecordSet。我有另一个想法。请多多包涵。 – 2011-05-24 13:16:31

+0

@Dan我编辑过的函数是特定的编组返回值。但是如果这改变了什么,我会感到惊讶,因为默认的编组器可以确定如何在接口指针中编组。顺便说一句,你是100%确定函数使用stdcall?当您混合使用cdecl和stdcall时,不平衡堆栈也经常发生。为什么使用C#中的cdecl会发生什么? – 2011-05-24 13:22:16