[Lazarus] Cross-compiling for Raspberry Pi2

Bo Berglund bo.berglund at gmail.com
Wed Sep 23 06:33:02 CEST 2015


On Tue, 22 Sep 2015 10:00:12 +0200, Michael Schnell
<mschnell at lumino.de> wrote:

>On 09/21/2015 04:42 PM, Bo Berglund wrote:
>> Unfortunately since the existing code is built on non-blocking serial 
>> communications and events to handle the data reception ...
>
>You can convert a blocking socket (or serial port receive) to be a 
>non-blocking Event-triggering (i.e. Delphi-Paradigm based) code by 
>encapsulating the blocking API in a thread and fire an event to the main 
>threads by TThread.Synchronize, TThread.Queue or 
>Application.QueueAsyncCall. Now you can do the complex work in the main 
>Thread event.
>
That is what I figured I could do with the TInetSocket I found in some
response here. I have verified it ships with FPC so I don't have to do
any install or such to get it too.

But since I did not find any documentation "for Dummies" on
TInetSocket I am not at all sure what I should do to add a therad to
manage it via an event handler.
I looked at the ssocket unit and found the declaration of TInetSocket
as follows:
[code]
 TInetSocket = Class(TSocketStream)
  Private
    FHost : String;
    FPort : Word;
  Protected
    Procedure DoConnect(ASocket : longint); Virtual;
  Public
    Constructor Create(ASocket : longint); Override; Overload;
    Constructor Create(const AHost: String; APort: Word); Overload;
    Property Host : String Read FHost;
    Property Port : Word Read FPort;
  end;
[/code]
At this level it seems very sparse so I have to drill down to its
ancestor TSocketStream:
[code]
  TSocketStream = class(THandleStream)
  Private
    FReadFlags: Integer;
    FSocketInitialized : Boolean;
    FSocketOptions : TSocketOptions;
    FLastError : integer;
    FWriteFlags: Integer;
    Procedure GetSockOptions;
    Procedure SetSocketOptions(Value : TSocketOptions);
    function GetLocalAddress: TSockAddr;
    function GetRemoteAddress: TSockAddr;
  Public
    Constructor Create (AHandle : Longint);virtual;
    destructor Destroy; override;
    function Seek(Offset: Longint; Origin: Word): Longint; override;
    Function Read (Var Buffer; Count : Longint) : longint; Override;
    Function Write (Const Buffer; Count : Longint) :Longint; Override;
    Property SocketOptions : TSocketOptions Read FSocketOptions
                                            Write SetSocketOptions;
    property LocalAddress: TSockAddr read GetLocalAddress;
    property RemoteAddress: TSockAddr read GetRemoteAddress;
    Property LastError : Integer Read FLastError;
    Property ReadFlags : Integer Read FReadFlags Write FReadFlags;
    Property WriteFlags : Integer Read FWriteFlags Write FWriteFlags;
  end;
[/code]
And then I have to go further to THandleStream:
[code]
  THandleStream = class(TStream)
  private
    FHandle: THandle;
  protected
    procedure SetSize(NewSize: Longint); override;
    procedure SetSize(const NewSize: Int64); override;
  public
    constructor Create(AHandle: THandle);
    function Read(var Buffer; Count: Longint): Longint; override;
    function Write(const Buffer; Count: Longint): Longint; override;
    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
override;
    property Handle: THandle read FHandle;
  end;
[/code]

And I am lost.....

In all of this where could I for instance check if there are received
data to read? The Read method being blocking would not really be
useful, right? I don't want to call anything that can potentially be
stuck and never return...
The minimum would be to be able to set a (short) timeout on the Read()
method. But I don't see that.

Do you have any pointers?
And btw thanks for your help so far! :)


-- 
Bo Berglund
Developer in Sweden





More information about the Lazarus mailing list