Перейти к содержанию
Fire Monkey от А до Я
  • 0

Аналог IStream для FMX


DirtyBorov

Вопрос

В VCL для передачи TStream из dll, обычно использую IStream, через пару TStreamAdapter/TOleStream. Но в FMX я что то не нашел им замену. Конечно, можно пойти путем что бы написать обертки для каждой OS. Но может есть какой то универсальный подход? 

Ссылка на комментарий

Рекомендуемые сообщения

  • 0
12 минут назад, DirtyBorov сказал:

передачи TStream из dll

так то длл чисто виндовая(реактОс"овая) фишка. Надеюсь вы же не собираетесь плагины для всех осей делать?

Ссылка на комментарий
  • 0
12 часов назад, Сысоев Максим сказал:

так то длл чисто виндовая(реактОс"овая) фишка. Надеюсь вы же не собираетесь плагины для всех осей делать?

Для Android и iOS конечно сомнительно. А вот в MacOS существуют - .dylib, .so. По сути это аналог dll, которые так же используют для plugin-ов.  

Попробую перефразировать вопрос - не совсем корректно его задал:

под Windows я могу написать приложение на FMX и в качестве plugin использовать dll. При этом, dll-plugin могут быть написаны вообще не на Delphi. При этом, для обмена данными используются interface (в том числе IStream), т.к. напрямую объекты передавать нельзя.

Могу ли я написать dylib или so на Delphi? Если нет, то могу ли я использовать so, написанную на другом языке и каков в таком случае будет подход по обмену данными между программой и плагином? Ну или возможно ли использовать BPL под MacOS (по сути это тоже dll)?

Допустим стоит задача, написать программу для Windows и MacOS, с поддержкой plugin. Получается что для windows мне нужно отдельно написать кучу dll + механизм обмена данными. И для MacOS сделать тоже самое. По сути, две разные программы!!!

Из этого и вытекает моей вопрос: могу ли я сделать универсальное решение? Что бы под windows компилировалась dll, а для MacOS - so. При этом для обмена использовался бы какой то общий механизм передачи данных (плюнем на совместимость с другими языками).

 Надеюсь так понятней. :) Сейчас у меня не стоит задачи делать плагины под MacOS. Но в дальнейшем весьма не исключена.

Ссылка на комментарий
  • 0

Я использую IStream, при компиляции под винду он лежит в WinApi.AtiveX, при компиляции под макось кажется в Types. TOleStream пришлось выдрать для макоси в отдельный файл, его же использую и для винды в вместо того что в VCL.ActiveX, так как у нас используется один сторонний компонент, который не работает если в fmx приложении подключены модули из VCL (а при подключении VCL.ActiveX к приложению это происходит)

Скрытый текст



{
  Вспомогательные классы для Com, так как Com под мак нет,
  то и модуль System.Win.ComObj в Mac версии приложения использовать нельзя.

  В этот модуль вынесены необходимые функции и классы для работы с интерфейсом IStream
}
unit suComHelpersUnit.FMX;

interface

uses
  {$IFDEF MSWINDOWS}
  WinApi.ActiveX,
  {$ELSE}
  System.Types,
  {$ENDIF}

  System.Classes, System.SysUtils,

  suStreamsConsts;

type
  TOleStream = class(TStream)
  private
    FStream: IStream;
  protected
    function GetIStream: IStream;
  public
    constructor Create(const Stream: IStream);

    function Read(var Buffer; Count: Longint): Longint; override;
    function Write(const Buffer; Count: Longint): Longint; override;
    function Seek(Offset: Longint; Origin: Word): Longint; override;
  end;

function Succeeded(Res: HResult): Boolean;

{ Raise EOleSysError exception if result code indicates an error }

procedure OleCheck(Result: HResult);

implementation
const
  SOleError = 'OLE error %.8x';

type
{ OLE exception classes }

  EOleError = class(Exception);

  EOleSysError = class(Exception)
  private
    FErrorCode: HRESULT;
  public
    constructor Create(const Message: UnicodeString; ErrorCode: HRESULT;
      HelpContext: Integer);
    property ErrorCode: HRESULT read FErrorCode write FErrorCode;
  end;

function Succeeded(Res: HResult): Boolean;
begin
  Result := Res and $80000000 = 0;
end;

{ Raise EOleSysError exception from an error code }

procedure OleError(ErrorCode: HResult);
begin
  raise EOleSysError.Create('', ErrorCode, 0);
end;

{ Raise EOleSysError exception if result code indicates an error }

procedure OleCheck(Result: HResult);
begin
  if not Succeeded(Result) then OleError(Result);
end;

{ EOleSysError }

constructor EOleSysError.Create(const Message: UnicodeString; ErrorCode: HRESULT;
  HelpContext: Integer);
var
  S: string;
begin
  S := Message;
  if S = '' then
  begin
    S := SysErrorMessage(Cardinal(ErrorCode));
    if S = '' then
      FmtStr(S, SOleError, [ErrorCode]);
  end;
  inherited CreateHelp(S, HelpContext);
  FErrorCode := ErrorCode;
end;

{ TOleStream }

constructor TOleStream.Create(const Stream: IStream);
begin
  FStream := Stream;
end;

function TOleStream.Read(var Buffer; Count: Integer): Longint;
begin
  OleCheck(FStream.Read(@Buffer, Count, @Result));
end;

function TOleStream.Seek(Offset: Integer; Origin: Word): Longint;
var
  NewPos: TsuLargeIntOrLargeUInt;
begin
  OleCheck(FStream.Seek(Offset, Origin, NewPos));
  Result := NewPos;
end;

function TOleStream.Write(const Buffer; Count: Integer): Longint;
begin
  OleCheck(FStream.Write(@Buffer, Count, @Result));
end;

function TOleStream.GetIStream: IStream;
begin
  Result := FStream;
end;

end.

и


unit suStreamsConsts;

{$I CompilerDefines.inc}

interface

uses
  Types;

type
  TsuLongIntOrFixedUInt = {$IFDEF VCL_XE8_OR_ABOVE}FixedUInt{$ELSE}Longint{$ENDIF};
  PsuLongIntOrFixedUInt = {$IFDEF VCL_XE8_OR_ABOVE}PFixedUInt{$ELSE}PLongint{$ENDIF};
  TsuLongIntOrDWORD = {$IFDEF VCL_XE8_OR_ABOVE}DWORD{$ELSE}Longint{$ENDIF};
  TsuLargeIntOrLargeUInt ={$IFDEF VCL_XE8_OR_ABOVE}UInt64{$ELSE}Int64{$ENDIF};

implementation

end.

 

 

Изменено пользователем Andrey Efimov
Добавлен тег "Спойлер"
Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...