5

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

谢谢!

4

2 回答 2

13

您可以使用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;

以防万一,如果您需要另辟蹊径(IStream从 C/C++ 接收),您可以使用TOleStream从中获取IStreamDelphi TStream

于 2012-08-03T23:32:02.230 回答
4
  • Microsoft C/C++ 编译的代码不能直接在 Delphi 对象上调用方法。例如,您必须将方法包装起来并呈现给 C++ 代码interface
  • 由 C++ Builder 编译的代码可以直接在 Delphi 对象上调用方法。

一般而言,包装一个 Delphi 类并将其呈现为一个类interface并不是一件容易的事。不能只通过接口公开原始方法的一个原因是 Delphi 方法使用了registerEmbarcadero 编译器专有的调用约定。您需要使用 Microsoft 编译器可以理解的调用约定,例如stdcall.

另一个并发症伴随着例外。您需要确保您的接口方法没有抛出异常,因为您的 C++ 代码无法捕获它们。一种选择是使用 Delphi 的safecall调用约定。safecall调用约定stdcall只是增加了将异常转换为HRESULT值的扭曲。

所有这些在概念上都相当直截了当,但可能需要一定数量的乏味样板代码。

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

于 2012-08-03T22:31:56.603 回答