是否可以将Delphi流(TStream子代)传递到用c/c++编写的DLL?DLL将用Microsoft c/c++编写。如果这不可能,那么我们使用C++Builder来创建DLL怎么样?或者,是否有任何流(FIFO)类可以在Microsoft C/C++和Delphi之间共享?
谢谢!
您可以使用IStream和TStreamAdapter来完成此操作。下面是一个快速示例(在D2007和XE2中测试):
uses
ActiveX;
procedure TForm1.DoSomething;
var
MemStream: TMemoryStream;
ExchangeStream: IStream;
begin
MemStream := TMemoryFile.Create;
try
MemStream.LoadFromFile('C:TestSomeFile.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
),您可以使用TOleStream从该IStream
获取Delphi TStream
。
- 由Microsoft C/C++编译的代码不能直接在Delphi对象上调用方法。例如,您必须将这些方法包装起来,并向C++代码呈现一个
interface
- C++编译器编译的代码可以直接在Delphi对象上调用方法
一般来说,封装一个Delphi类并将其表示为interface
并不是一件小事。不能通过接口公开原始方法的一个原因是Delphi方法使用了Embarcadero编译器专有的register
调用约定。您需要使用Microsoft编译器能够理解的调用约定,例如stdcall
。
另一个复杂情况也有例外。您需要确保您的接口方法没有抛出异常,因为不能期望您的C++代码捕获它们。一种选择是使用Delphi的safecall
调用约定。safecall
调用约定是stdcall
,但添加了将异常转换为HRESULT
值的扭曲。
所有这些在概念上都相当直接,但可能需要一定数量乏味的样板代码。
值得庆幸的是,在TStream
的情况下,您可以使用TStreamAdapter
将Delphi流公开为COM IStream
。事实上,这个小类的源代码展示了如何处理我上面描述的问题。