调用Delphi DLL并向其传递C#流

调用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方法时遇到一些问题。

我有一个用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方法时遇到一些问题。如果一切正常,该方法还应该在
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
);