调用Delphi DLL并向其传递C#流
我有一个用Delphi编写的DLL,从中我只知道他的签名,如:调用Delphi DLL并向其传递C#流,c#,.net,delphi,pinvoke,dllimport,C#,.net,Delphi,Pinvoke,Dllimport,我有一个用Delphi编写的DLL,从中我只知道他的签名,如: function GeResultToStream(Param1: PChar; Param2: PChar; Param3:PChar; Param4: integer; out Param5: DWord; ParamStream: IStream; Error: PChar; ErrorSize: integer):BOOL;stdcall; external 'MYDLL.dll'; 从C#调用此DLL方法时遇到一些问题。
function GeResultToStream(Param1: PChar; Param2: PChar; Param3:PChar; Param4: integer; out Param5: DWord; ParamStream: IStream; Error: PChar; ErrorSize: integer):BOOL;stdcall; external 'MYDLL.dll';
从C#调用此DLL方法时遇到一些问题。如果一切正常,该方法还应该在ParamStream
中传输一些数据,并返回true
我尝试了以下操作(以及DLL的方法参数中的其他各种更改),但没有成功(每次使用引用或out参数调用此函数时,都会出现错误):
我的猜测是,我不明白如何正确翻译签名以在C#中使用它。如果需要,我可以提供更多信息(比如我收到的错误,但大部分都是内存损坏)。你的翻译是错误的。我不确定您是如何将
类型为DWORD
的参数转换为char[]
的。这应该是out uint
。而且流
不应该是ref
,而且需要是IStream
接口,而不是流
类
p/invoke应该是这样的:
[DllImport(_dllLocation, CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi, EntryPoint = "GeResultToStream")]
public static extern bool GeResultToStream(
string Param1,
string Param2,
string Param3,
int Param4,
out uint Param5,
ComTypes.IStream ParamStream,
string Error,
int ErrorSize
);
请注意,这假设是2007或更早版本的Delphi,其中PChar
映射到PAnsiChar
。如果Delphi版本晚于该版本,并且PChar
是PWideChar
,则使用CharSet.Unicode
我还假设所有字符串参数都用于将数据从调用者传递给被调用者。但最后一个字符串参数,Error
可能没有这些语义。它可能是用来传递错误文本的。因此,应该使用StringBuilder
代替string
来实现
当然,您需要从某处获得IStream
的实现。例如:。我很难就此向您提供建议,因为您没有提供有关如何调用函数的任何重要细节。您已经更改了所有参数的名称,因此我们无法猜测其语义
随着调试的进行,我可以看到这个问题有点像火车失事。我希望我被证明是错的。我想你应该使用System.Runtime.InteropServices.ComTypes.IStream
我想你可能会有点困惑。NET对象类型(如C#Streams)无法有意义地传递给Delphi,除非我们在Delphi端引入一些非常难以编写的.NET互操作代码。事实上,你所做的是疯狂的。事实上,使用Stream对象是一个错误。正如David Heffernan所说,通过使用一个IStream接口和一个基本的包装器,我终于获得了流信息。事实上,你的p/invoke观察有帮助。谢谢你的帮助!我没有提供更多的细节,因为不幸的是,我只有一个关于我使用的dll的有限文档,而字段是一种外来语言的名称。
[DllImport(_dllLocation, CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi, EntryPoint = "GeResultToStream")]
public static extern bool GeResultToStream(
string Param1,
string Param2,
string Param3,
int Param4,
out uint Param5,
ComTypes.IStream ParamStream,
string Error,
int ErrorSize
);