如何将流从 Delphi 传递到 C#?

How to pass a stream from Delphi to C#?

Streams 对我来说非常神秘,所以请耐心和友好:) 我正在尝试在 Delphi 中创建一个 Stream,我可以将其作为参数传递给 C#。有人知道怎么做吗?

请注意 我可以从我的 Delphi 项目中调用 C# 函数,如下所示。我已按照 this tutorial 从我的 C# 项目创建 DLL 并在 Delphi.

中实现该 DLL
procedure TForm1.Button1Click(Sender: TObject);
var
    Stream : TStream;
    Baz : TBaz;
begin
    Baz := TBaz.Create(Self);
    // Create Stream & call Bar() with the created Stream as parameter
    Baz.Bar(?param?);
end;

我的 C# 项目如下所示:

public class Baz
{
    public void Bar(?param?)
    {
        // Get stream here
    }
}

我非常感谢任何帮助,sheers!


编辑:

Streams 是特定于每个编译器的实现的,因此您不能将(本机)Delphi TStream 传递给 C# 并期望它在那里工作。同样,C# Stream 与(本机)Delphi TStream 不兼容,因此您也不能采用其他方式。

在 C# 类 和 Delphi 类 之间进行某种形式的互操作性(使用大量肮脏的 hack)可能是可能的,但坦率地说,它'将做很多工作却收效甚微,特别是(无意侮辱)您当前的经验水平(因为您认为流“神秘”)。

如果它是您要传递的文件,请传递文件名,让 C# 端分配一个 C# 流来访问它。

编辑:您可以使用 IStream 接口包装(本机)Delphi TStream 实例并将此接口传递给 C#,然后它应该能够访问(本机)Delphi TStream来自(托管)C# 代码。请参阅 Dalija Prasnikar 的回答。

为了互操作性目的,Delphi 和 C# 都支持 IStream 接口。您可以使用 TStreamAdapter 包装任何流。如果您在 Delphi 端构建流,您需要确保包装流实例的寿命比 IStream 包装器更长,或者您需要将流的所有权传递给适配器。

uses
  Winapi.ActiveX,
  System.Classes; 

var
  FileStream: TFileStream;
  Stream: IStream;
begin
  FileStream := TFileStream.Create(...);
  try
    Stream := TStreamAdapter.Create(FileStream);
    // use stream
    Baz.Bar(Stream);
  finally
    Stream := nil;
    FileStream.Free;
  end;
end;

var
  FileStream: TFileStream;
  Stream: IStream;
begin
  FileStream := TFileStream.Create(...);
  Stream := TStreamAdapter.Create(FileStream, soOwned);
  // use stream
  Baz.Bar(Stream);
end;

文档:

当然,您始终可以将文件名传递给 C#,并在 C# 端构造流。