Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Процедура объекта как параметр потока / 9 сообщений из 9, страница 1 из 1
04.05.2021, 22:58
    #40068450
HOME_X
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура объекта как параметр потока
Доброго дня господа !

Имею код, хочу параметризировать вызов метода в потоке

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
--------------------------------------------------------
implementation

  function MainThread(Param: Pointer): Integer;
  begin
    Result:=0;
    TAddSpan(Param).ExecuteLoop;
    PostMessage(TAddSpan(Param).Handle,Wm_ExitThread,0,LParam(Param));
  end;

  function MainThreat(Param: Pointer): Integer;
  begin
    Result:=0;
    TAddSpan(Param).ExecuteItem;
    PostMessage(TAddSpan(Param).Handle,Wm_ExitThread,0,LParam(Param));
  end;


  function Create_AddSpan(aFile: PAnsiChar; aList: PAnsiChar; aKind: OleVariant; aBars: OleVariant; aHandle: OleVariant; var aSql: OleVariant; var aRecordSet: OleVariant): Integer;
  var
    S: String;
    Id: Cardinal;
  begin
    Result:=1;
    A:=TAddSpan.Create();
    A.Handle := aHandle;
    if (Integer(aKind) =2) then Result:=BeginThread(Nil,0,@MainThread,A,0,Id);
    if (Integer(aKind) =3) then Result:=BeginThread(Nil,0,@MainThreat,A,0,Id);
  end;
--------------------------------------------------------




Хотел бы иметь такую архитектуру

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
--------------------------------------------------------
type
  TCallBack = function: THandle of object;

  TCallRecord = record
    methods: TCallBack;
  end;

implementation

  function MainAlter(Param: Pointer): Integer;
  var MainHandle: THandle;
      A: TCallRecord;
  begin
    Result:=0;
    A:=TCallRecord(Param^);
    MainHandle:=TCallBack(A.methods);
    PostMessage(MainHandle,Wm_ExitThread,0,LParam(Param));
  end;

  function Create_AddSpan(aFile: PAnsiChar; aList: PAnsiChar; aKind: OleVariant; aBars: OleVariant; aHandle: OleVariant; var aSql: OleVariant; var aRecordSet: OleVariant): Integer;
  var
    S: String;
    H:  THandle;
    R1, R2: TCallRecord;
    Id: Cardinal;
  begin
    Result:=1;
    A:=TAddSpan.Create();
    A.Handle := aHandle;
    R1.methods:=A.ExecuteLoop1;
    R2.methods:=A.ExecuteItem1;
    if (Integer(aKind) =2) then Result:=BeginThread(Nil,0,@MainAlter,@R1,0,Id);
    if (Integer(aKind) =3) then Result:=BeginThread(Nil,0,@MainAlter,@R2,0,Id);
  end;
--------------------------------------------------------



Ошибка памяти - подскажите что делаю не так
Спасибо
...
Рейтинг: 0 / 0
04.05.2021, 23:25
    #40068454
Cobalt747
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура объекта как параметр потока
попробуй передавать только TCallBack вместо TCallRecord
и не вижу необходимости дополнительно приводить тип метода

или вообще передавай только Integer(aKind)
...
Рейтинг: 0 / 0
04.05.2021, 23:47
    #40068456
HOME_X
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура объекта как параметр потока
Cobalt747

или вообще передавай только Integer(aKind)


Указатель на Integer ?
Приведите пожалуйста пример
...
Рейтинг: 0 / 0
05.05.2021, 00:15
    #40068461
HOME_X
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура объекта как параметр потока
Уточняю - мне не совсем ясно как передать
aKind и указатель на текущий объекта - нужно ДВА параметра, соответственно нужен тип record
...
Рейтинг: 0 / 0
05.05.2021, 00:29
    #40068464
Maxim Rusov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура объекта как параметр потока
HOME_X
Уточняю - мне не совсем ясно как передать
aKind и указатель на текущий объекта - нужно ДВА параметра, соответственно нужен тип record

Аллоцируй record динамически и передавай указатель. BeginThread сам так и делает. Только освободить не забудь в MainAlter.

PS. MainThreat - это 5
...
Рейтинг: 0 / 0
05.05.2021, 00:50
    #40068468
HOME_X
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура объекта как параметр потока
Cobalt747
попробуй передавать только TCallBack вместо TCallRecord


Здесь тоже не совсем ясно - я передаю ФУНКЦИЮ объекта, соответственно заключаю
ее в Pointer, но вероятно передается результат выполнения

if (Integer(aKind) =3) then Result:=BeginThread(Nil,0,@MainAlter,Pointer(A.ExecuteItem1),0,Id);

пожалуйста приведите пример Вашего предложения
...
Рейтинг: 0 / 0
05.05.2021, 01:01
    #40068471
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура объекта как параметр потока
HOME_Xя передаю ФУНКЦИЮ объекта, соответственно заключаю ее в Pointer

Этот код не должен компилироваться в принципе, поскольку указатель на метод класса не
может быть приведён к любому другому указателю. Если оно таки компилируется - рапортуй баг
эмбаркадере.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
05.05.2021, 07:49
    #40068478
Cobalt747
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура объекта как параметр потока
HOME_X,

да, насчет передачи метода через Pointer это я ошибся.

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

Так что да, используй указатель на рекорд new/dispose
...
Рейтинг: 0 / 0
05.05.2021, 16:08
    #40068630
HOME_X
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Процедура объекта как параметр потока
Cobalt747,

Решил задачу через добавление поля в основной обьект

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
  function MainThread(Param: Pointer): Integer;
  begin
    Result:=0;
    if(TAddSpan(Param).Kind=2) then TAddSpan(Param).ExecuteLoop;
    if(TAddSpan(Param).Kind=3) then TAddSpan(Param).ExecuteItem;
    PostMessage(TAddSpan(Param).Handle,Wm_ExitThread,0,LParam(Param));
  end;


------------------------------------------------------------------------------------------------

  TAddSpan = class(TObject)
  private
    iKind:    Integer;
    sSql:     String;
 protected
    //
 public
    constructor Create(aFile: String; aBars: TProgressBar; aHandle: THandle; var aSql: OleVariant; var aRecordSet: OleVariant); virtual;
    destructor  Destroy; override;
    property    Kind: Integer  read iKind write iKind;



  A:=TAddSpan.Create(iif((Integer(aKind)=0)or(Integer(aKind)=3),'[Path]'+vbLine+String(aList),String(aFile)),B,H,aSql,aRecordSet);
  A.Kind:=aKind;

  if (Integer(aKind) =2) then Result:=BeginThread(Nil,0,@MainThread,A,0,Id);
  if (Integer(aKind) =3) then Result:=BeginThread(Nil,0,@MainThread,A,0,Id);



Т.е. все равно работать через RECORD (и обьект в некотором смысле и есть такой RECORD)

Спасибо

Модератор: Как мне оформить свое сообщение?
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Процедура объекта как параметр потока / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]