Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何将Delphi流传递给c/c++;动态链接库_C++_Delphi_Stream - Fatal编程技术网

C++ 如何将Delphi流传递给c/c++;动态链接库

C++ 如何将Delphi流传递给c/c++;动态链接库,c++,delphi,stream,C++,Delphi,Stream,是否可以将Delphi流(TStream子代)传递给用c/c++编写的DLL?DLL将用Microsoft c/c++编写。如果这是不可能的,如果我们使用C++ Builder来创建DLL呢?或者,是否有任何流(FIFO)类可以在Microsoft C/C++和Delphi之间共享 谢谢 由Microsoft C/C++编译的代码不能直接在Delphi对象上调用方法。例如,你必须把方法封装起来,并提交给C++代码,一个接口。李> 由C++ Builder编译的代码可以直接调用Delphi对象的

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

谢谢

  • 由Microsoft C/C++编译的代码不能直接在Delphi对象上调用方法。例如,你必须把方法封装起来,并提交给C++代码,一个<代码>接口<代码>。李>
  • 由C++ Builder编译的代码可以直接调用Delphi对象的方法。
一般来说,包装一个Delphi类并将其显示为一个
接口
并不是一件简单的事情。不能仅通过接口公开原始方法的一个原因是,Delphi方法使用Embarcadero编译器专有的
寄存器
调用约定。您需要使用Microsoft编译器能够理解的,例如
stdcall

另一个复杂情况也有例外。您需要确保接口方法没有抛出异常,因为您的C++代码不能预期捕获它们。一种选择是使用Delphi的调用约定。
safecall
调用约定是
stdcall
,但增加了一个扭曲,将异常转换为
HRESULT

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

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

您可以使用和来完成此操作。下面是一个快速示例(在D2007和XE2中测试):


以防万一,如果您需要换一种方式(从C/C++接收
IStream
),您可以使用从
IStream
获取Delphi
TStream

,这在某些地方有点痛苦,但ActiveX单元定义了IStream,这是Win32 API中定义的接口。现在我想不出确切的代码,我想我可能已经把它扔掉了。但是TStreamAdapter和TOLEStream就在那里的某个地方。谷歌先生会知道答案的。@Tony TStreamAdapter走错了路。它接受一个
IStream
,并将其调整为
TStream
。不,它没有
TStreamAdapter
TStream
作为输入,并将其包装在
IStream
实现中。@Remy你说得对。我无法想象我是怎么了。我删除我的答案。谢谢你纠正我。我记不起哪个是哪个了(一个是到一个Istream,另一个是从。-1,因为
TStreamAdapter
是专门编写的,用于将
TStream
封装在一个与COM兼容的
Istream
中,任何可以使用COM的语言都可以使用它。@Ken谢谢,你说得很对。我选择保留这个答案是因为有两个要点。还有关于实现COM接口适配器的更一般的建议。这对于想要流以外的东西的人可能很有用。删除Downvote,因为更正了不正确的部分。:-)这与以前执行此操作的模糊记忆相符+1@Ken怀特:谢谢你的回答。一旦你知道了就不难了:-)
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;