如何将Delphi Stream传递给c / c ++ DLL

时间:2012-08-03 21:20:28

标签: c++ delphi stream

是否可以将Delphi流(TStream后代)传递给用c / c ++编写的DLL? DLL将用Microsoft c / c ++编写。如果那是不可能的,那么如果我们使用C ++ Builder来创建DLL呢?或者,是否有可以在Microsoft C / C ++和Delphi之间共享的Stream(FIFO)类?

谢谢!

2 个答案:

答案 0 :(得分:12)

您可以使用IStreamTStreamAdapter执行此操作。这是一个简单的例子(在D2007和XE2中测试):

uses
  ActiveX;

procedure TForm1.DoSomething;
var
  MemStream: TMemoryStream;
  ExchangeStream: IStream;
begin
  MemStream := TMemoryFile.Create;
  try
    MemStream.LoadFromFile('C:\Test\SomeFile.txt');
    MemStream.Position := 0;
    ExchangeStream := TStreamAdapter.Create(MemStream) as IStream;
    // Pass ExchangeStream to C++ DLL here, and do whatever else
  finally
    MemStream.Free;
  end;
end;

以防万一,如果您需要采用其他方式(从C / C ++接收IStream),您可以使用TOleStreamIStream转到Delphi { {1}}。

答案 1 :(得分:4)

  • Microsoft C / C ++编译的代码无法直接在Delphi对象上调用方法。例如,您必须将方法包装起来并向C ++代码提供interface
  • C ++ Builder编译的代码可以直接在Delphi对象上调用方法。

通常,包装Delphi类并将其呈现为interface并非完全无关紧要。您不能仅通过接口公开原始方法的一个原因是使用Embarcadero编译器专有的register调用约定的Delphi方法。您需要使用Microsoft编译器可以理解的calling convention,例如stdcall

另一个复杂因素是异常。您需要确保您的接口方法不会抛出异常,因为您的C ++代码无法捕获它们。一种选择是使用Delphi的safecall调用约定。 safecall调用约定为stdcall,但附加的扭曲将异常转换为HRESULT值。

概念中所有相当直接,但可能需要一定量的繁琐的样板代码。

值得庆幸的是,在TStream的情况下,您可以使用TStreamAdapter将Delphi流公开为COM IStream。实际上,这个小类的源代码显示了如何处理我上面描述的问题。