How to pass a Delphi Stream to a c/c++ DLL

后端 未结 2 514
孤独总比滥情好
孤独总比滥情好 2021-01-05 22:29

Is it possible to pass a Delphi stream (TStream descendant) to a DLL written in c/c++? DLL will be written in Microsoft c/c++. If that is not possible, how about if we use C

相关标签:
2条回答
  • 2021-01-05 23:08

    You can do this using IStream and TStreamAdapter. Here's a quick example (tested in D2007 and 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;
    

    Just in case, if you need to go the other way (receiving an IStream from C/C++), you can use TOleStream to get from that IStream to a Delphi TStream.

    0 讨论(0)
  • 2021-01-05 23:15
    • Code compiled by Microsoft C/C++ cannot call methods directly on a Delphi object. You would have to wrap the methods up and present, to the C++ code, an interface, for example.
    • Code compiled by C++ Builder can call methods directly on a Delphi object.

    In general, wrapping up a Delphi class and presenting it as an interface is not completely trivial. One reason why you can't just expose the raw methods via an interface is that the Delphi methods using the register calling convention which is proprietary to Embarcadero compilers. You'd need to use a calling convention that is understood by the Microsoft compiler, e.g. stdcall.

    Another complication comes with exceptions. You would need to make sure that your interface methods did not throw exceptions since your C++ code can't be expected to catch them. One option would be to use Delphi's safecall calling convention. The safecall calling convention is stdcall but with an added twist that converts exceptions into HRESULT values.

    All rather straight forward in concept, but probably requiring a certain amount of tedious boilerplate code.

    Thankfully, in the case of TStream, you can use TStreamAdapter to expose the Delphi stream as a COM IStream. In fact, the source code for this small class shows how to handle the issues I describe above.

    0 讨论(0)
提交回复
热议问题