Forum > General

[SOLVED] Thread => AlwaysWaitForExecute ?

<< < (2/4) > >>

Fred vS:

--- Quote ---show us the code
--- End quote ---

Ok, ok,...  :-[

Here the Program =>

--- Code: ---program prog_graout;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils, Classes, fpg_base, fpg_main, fpg_form,
  h_graout;

type
  Ttest = class(TfpgForm)
  private
  public
    procedure AfterCreate; override;
  end;
 
 type
   TgraoutThread= class(TThread)
  protected
  procedure Execute; override;
    public
  constructor Create(CreateSuspended: boolean;
      const StackSize: SizeUInt = DefaultStackSize);
end;

var
 graoutThread : TgraoutThread;

constructor TgraoutThread.Create(CreateSuspended: boolean;
  const StackSize: SizeUInt);
  begin
   inherited Create(CreateSuspended, StackSize);
  FreeOnTerminate := true;
    end;
 
  procedure TgraoutThread.execute();
  begin
  graout_mainproc() ;
  end;

procedure Ttest.AfterCreate;
begin
  Name := 'test';
  SetPosition(459, 222, 300, 250);
  WindowTitle := 'I am the main program';
 end;

procedure MainProc;
var
  frm: Ttest;
  libpath : string;
  begin
    {$IFDEF Windows}
  libpath := IncludeTrailingBackslash(ExtractFilePath(ParamStr(0))) + 'graout.dll' ;
    {$else}
 
  libpath := IncludeTrailingBackslash(ExtractFilePath(ParamStr(0))) + 'libgraout.so' ;
   {$endif}
  fpgApplication.Initialize;
  try
  graout_loadlib(libpath) ; /// load library and create thread
 
  graoutthread := TgraoutThread.create(true); // create the thread
 
  graoutthread.execute ;    /// run main graphical procedure of library via thread.execute
 
  frm := Ttest.Create(nil);  // create main form
  fpgApplication.MainForm := frm;
  frm.Show;
  fpgApplication.Run;  // run main application
  finally

  graout_unloadlib() ;  // unload library

   frm.Free;
  end;
end;

begin
  MainProc;
end.

--- End code ---

Here the Library =>

--- Code: ---library graout;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  SysUtils, Classes, fpg_base, fpg_main, fpg_form;

type
  TGraout = class(TfpgForm)
  private
   public
    procedure AfterCreate; override;
  end;
 
procedure TGraout.AfterCreate;
begin
  Name := 'graout';
  SetPosition(492, 285, 500, 250);
  WindowTitle := 'I am a graphic out library';
 end;


procedure graout_mainproc; cdecl;
var
  frm: TGraout;
begin
  fpgApplication.Initialize;
  try
    frm := TGraout.Create(nil);
    fpgApplication.MainForm := frm;
    frm.Show;
    fpgApplication.Run;
  finally
    frm.Free;
  end;
end;

exports
  graout_mainproc name 'graout_mainproc';

end.

--- End code ---

And here the wrapper to the library =>

--- Code: ---unit h_graout ;

interface

uses
  DynLibs;

var
  graout_mainproc : procedure(); cdecl;
 
 LibHandle:TLibHandle=dynlibs.NilHandle; // this will hold our handle for the lib
 ReferenceCounter : cardinal = 0;  // Reference counter
         
function graout_isLoaded() : boolean; inline;
function graout_loadlib(const libfilename: string): boolean; // load the lib
procedure graout_unloadlib(); // unload the lib

implementation

function graout_isloaded(): boolean;
begin
 Result := (LibHandle <> dynlibs.NilHandle);
end;

function graout_loadlib(const libfilename: string): boolean;
begin
   Result := False;
  if LibHandle<>0 then
begin
 Inc(ReferenceCounter);
result:=true
end  else begin
    if Length(libfilename) = 0 then exit;
    LibHandle:=DynLibs.LoadLibrary(libfilename);
  if LibHandle <> DynLibs.NilHandle then
       begin
    try
      Pointer(graout_mainproc) :=
        GetProcAddress(LibHandle, 'graout_mainproc');
       
    Result := graout_isLoaded;
    ReferenceCounter:=1;   
      except
      graout_unloadlib;
    end;
  end;
end;
end;

procedure graout_unloadlib();
begin
// < Reference counting
  if ReferenceCounter > 0 then
    dec(ReferenceCounter);
  if ReferenceCounter > 0 then
    exit;
  // >
  if LibHandle <> DynLibs.NilHandle then
  begin
    DynLibs.UnloadLibrary(LibHandle);
    LibHandle := DynLibs.NilHandle;
  end;
end;

end.

--- End code ---

Fre;D

Leledumbo:

--- Quote from: Fred vS on December 09, 2014, 02:03:14 am ---Ok, ok,...  :-[

--- End quote ---
Now that's clear. Your library's thread function creates another fpGUI application & form instance, which has separate RTL from your app, but executes as a part of your app. I'm not quite sure about this behavior, it's more complex than just "GUI update from child thread" problem, but probably the same explanation applies.

User137:
You're calling the execute function directly here

--- Code: ---TestThread.execute(); /////// Here do not give te control back
--- End code ---

I'm assuming you want to run it as a separate thread, so:

--- Code: ---TestThread.start();
--- End code ---

Fred vS:

--- Quote ---I'm assuming you want to run it as a separate thread, so:

TestThread.start();
--- End quote ---

 =>


--- Quote ---An unhandled exception occurred at $00007FAAFB7B0214:
EThread: CheckSynchronize called from non-main thread "$7FAAFB675700"
  $00007FAAFB7B0214
  $00007FAAFB7D2A08
  $00007FAAFB7D26EE
  $00007FAAFB7D7176

--- End quote ---

engkin:
Who loaded the lib that contains the proc that you called in your test thread, the test thread itself or the main thread?

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version