Dynamiczne wywoływanie różnych wątków

0

Witam.
Mam problem z dynamicznym wywoływaniem wątków. Problem tkwi w tym że nie można wywołać tak wątku (funkcja jest tylko po to by mi ID Thread'a zwracała kontrolnie)

RegisterThread('TEST','001',True,CMDConsole);

bo jest niezgodność typów.
Nie mogę dać CMDConsole zamiast TThread bo by się odwoływało tylko do tego jednego rodzaju wątku a ja w późniejszym czasie chcę dodać ich kilkanaście jak nie więcej...
Co do tworzenia wątków to każdy ma stałe procedury Create i Destroy.

W tablicy rekordu umieszczam ID (PID), Handle - Tu ma się umieszczać ID i wywołany wątek by można było swobodnie nim później operować na bazowych procedurach ew funkcjach które dojdą później (Create i Destroy itp)

uses
   QCMDConsole;


type RThreadNFO = record
  PID:Integer;
  Name:String;
  Title:String;
  Handle:TThread;
  Active:Boolean;
end;


var
 TThreadTBL         : array of RThreadNFO;


function TBodyForm.RegisterThread(Name,Title:String;Mode:Boolean;CThread:TThread):Integer;
var
 I       : Integer;
begin
 for I := 0 to High(TThreadTBL) do
  if TThreadTBL[I].Active = False then Break;

 if I > High(TThreadTBL) then SetLength(TThreadTBL,High(TThreadTBL)+2);

 I:=High(TThreadTBL);
 TThreadTBL[I].PID:=I;
 TThreadTBL[I].Name:=Name;
 TThreadTBL[I].Title:=Title;
 TThreadTBL[I].Handle:=CThread.Create(Mode);
 TThreadTBL[I].Active:=True;
 Result:=TThreadTBL[I].PID;

end;

Co do Wątku to wygląda tak

 unit QCMDConsole;

interface

uses
  Dialogs,Windows, Messages, SysUtils, Classes, UnitedCMD;

const
 CMD_REFRESH = 300;

type
  CMDConsole = class(TThread)
  private
    FThreadID      : THandle;
    FProcessID     : Integer;
    CMD            : TUnitedCMD;

   procedure EventRevData(Sender:TObject;Data:String);
   procedure SetName;

  protected

  public
    constructor Create(Mode:Boolean);
    destructor Destroy; override;
    procedure Execute; override;
    procedure Command(Data:String);

    property PID: Integer read FProcessID;
    property ThreadID :THandle read FThreadID;
  end;

implementation

{$IFDEF MSWINDOWS}
type
  TThreadNameInfo = record
    FType: LongWord;     // must be 0x1000
    FName: PChar;        // pointer to name (in user address space)
    FThreadID: LongWord; // thread ID (-1 indicates caller thread)
    FFlags: LongWord;    // reserved for future use, must be zero
  end;
{$ENDIF}

{ CMDConsole }


procedure CMDConsole.SetName;
{$IFDEF MSWINDOWS}
var
  ThreadNameInfo: TThreadNameInfo;
{$ENDIF}

begin
{$IFDEF MSWINDOWS}
  ThreadNameInfo.FType := $1000;
  ThreadNameInfo.FName := 'CMDConsole';
  ThreadNameInfo.FThreadID := $FFFFFFFF;
  ThreadNameInfo.FFlags := 0;

  try
    RaiseException( $406D1388, 0, sizeof(ThreadNameInfo) div sizeof(LongWord), @ThreadNameInfo );
  except
  end;
{$ENDIF}
end;


constructor CMDConsole.Create(Mode:Boolean);
begin
  inherited Create(Mode);
    CMD            := TUnitedCMD.Create(CMD);
    CMD.Refresh    := CMD_REFRESH;
    CMD.OnData     := EventRevData;
    CMD.Activ      := True;
end;

destructor CMDConsole.Destroy;
begin
 
 CMD.Activ:=False;
 CMD.Free;
end;

procedure CMDConsole.Command(Data:String);
begin
  CMD.SendCommand(Data);
end;

procedure CMDConsole.EventRevData(Sender:TObject;Data:String);
begin
 ShowMessage(Data);
end;

procedure CMDConsole.Execute;
begin
  SetName;
  { Place thread code here }
end;

end.

Wątek w całości działa poprawnie bo już go testowałem statycznie.

Jak by ktoś mógł pomóc w rozwiązaniu problemu był bym wdzięczny, bo wujek google nie dał żadnych rezultatów.

0

RegisterThread przyjmuje parametr typu TThread a Ty mu dajesz CMDConsole (btw powinienes to nazwac __T__CmdConsole) który nie jest tym typem. Dziedziczy po TThread ale nim nie jest. Poczytaj o rzutowaniu. http://4programmers.net/Delphi/Rzutowanie

0
  1. @cimak to nie ma znaczenia - CMDConsole dziedziczy po TThread i jako taki bez problemów może być przekazany do tej metody
  2. TThreadTBL[I].Handle:=CThread.Create(Mode); to nie ma prawa bytu - CThread to już konkretne instancja obiektu.
  3. CMD := TUnitedCMD.Create(CMD); co tam robi to CMD w nawiasie - przecież to jest AV jak byk
  4. podaj dokładnie to co wypisuje kompilator i do której linii się odnosi bo jestem przekonany, że to nie tego dotyczy błąd
  5. nie wiem czy zdajesz sobie sprawę z tego, że cały ten wątek się zamknie zaraz po utworzeniu (generalnie w tej postaci jest on całkowicie zbędny)
0

To nie ma znaczenia czy wątek nazwę TCMDConsole czy CMDConsole to będzie to samo.
Rzutowanie nie działa bo nawet gdy się skompiluje to przy uruchomieniu daje błędy dostępu do pamięci

Oto błąd który występuje podczas kompilacji, przy linii z wywoływaniem funkcji

 RegisterThread('TEST','001',True,CMDConsole);

debugger mówi o nie właściwym typie CMDConsole
[DCC Error] Body.pas(117): E2010 Incompatible types: 'TThread' and 'Class reference'

A co do samego wątku jak mówiłem jest złożony i działa poprawnie bo gdy wywołam go statycznie tzn
var
ms:CMDConsole;
proc ...;
begin
ms:=CMDConsole.Create(True);

a w button dam
ms.Command(Edit1.Text);

to wszystko działa.

Nie mogę zadeklarować CThread:TThread tak CThread:CMDConsole bo w ten sposób odwołuje się tylko do tego wątku (CMDConsole) a ja będę tą procedurą rejestrował też inne wątki (o nazwach Status, FTP itp)

co do tego cmd w tym AV to nie zauważyłem różnicy między tym a nil albo innym śmieciem bo komponent ma constructor TUnitedCMD.Create(AOwner: TComponent); a AOwner: TComponent jest nie używany (sobie jest bo jest) więc dałem byle co żeby kompilator się nie czepiał ;]

Dopisze że problem tkwi tylko w przekazaniu CMDConsole w zmiennej CThread

a to
TThreadTBL[I].Handle:=CThread.Create(Mode);
ma prawo bytu bo jak dasz to działa poprawnie, a CThread to zmienna przechowująca to CMDConsole
TThreadTBL[I].Handle:=CMDConsole.Create(True);

0

[DCC Error] Body.pas(117): E2010 Incompatible types: 'TThread' and 'Class reference'

Jest błąd, bo przekazujesz do funkcji nazwę klasy, a nie zmiennej.

2

jakbyś normalnie nazywał typy to by błąd wyłapał od razu każdy a jak piszesz gówniany kod to potem sam nie wiesz co robisz

0

Sugerowałem się tym że CMDConsole (wątek) należy do TThread ale to nie działa nie wiem czemu, proszę o pomoc bo nie mam pomysłu jak rozwiązać ten problem.

0
proqix napisał(a)

To nie ma znaczenia czy wątek nazwę TCMDConsole czy CMDConsole to będzie to samo.

no widzisz, jednak to ma znaczenie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1