Сервер без формы
От: k_artem  
Дата: 07.11.02 19:59
Оценка:
Я пытался сделать резидентную прогу без создания формы в C++ Builder
Написал так:

void __fastcall OnWrite (TObject *Sender,TCustomWinSocket *Socket)
{
}

...
TSeverSocket *SeverSocket1 = new TSeverSocket;
ServerSocket1->OnClientWrite = OnWrite;
...

Все это делалось в Console Application с VCL
При компиляции выходит ошибка
E2034 Cannot convert 'void (_fastcall *)(TObject *,TCustomWinSocket *)' to 'void (_fastcall * (_closure )(TObject *,TCustomWinSocket *))(TObject *,TCustomWinSocket *)'

Подскажите, что делать?
Re: Сервер без формы
От: Fantasist  
Дата: 07.11.02 20:29
Оценка:
Здравствуйте k_artem, Вы писали:

KA>Я пытался сделать резидентную прогу без создания формы в C++ Builder

KA>Написал так:

KA>void __fastcall OnWrite (TObject *Sender,TCustomWinSocket *Socket)

KA>{
KA>}

KA>...

KA>TSeverSocket *SeverSocket1 = new TSeverSocket;
ServerSocket1->>OnClientWrite = OnWrite;
KA>...

KA>Все это делалось в Console Application с VCL

KA>При компиляции выходит ошибка
KA>E2034 Cannot convert 'void (_fastcall *)(TObject *,TCustomWinSocket *)' to 'void (_fastcall * (_closure )(TObject *,TCustomWinSocket *))(TObject *,TCustomWinSocket *)'

KA>Подскажите, что делать?


Несоответствие типов. OnClientWrite — исмеет тип указателя на метод класса — это такой 8-ми битный указатель, где храниться указатель на объект, чей метод надо вызвать и указатель на саму функцию(метод). Преобразовать можно так:

((TMethod)(ServerSocket1->OnClientWrite)).Code=(void*)OnWrite;
((TMethod)(ServerSocket1->OnClientWrite)).Data=0;

Надеюсь, что так. Так я делал в Delphi, и подозреваю, что в Builder'e так же, но проверить не могу.
Re: Сервер без формы
От: Hacker_Delphi Россия  
Дата: 07.11.02 21:43
Оценка:
Здравствуйте k_artem, Вы писали:
Объяви класс типа такого:
class MyHandler: public TObject
{
  public:
  MyHandler()
  {
  }
  void __fastcall OnWrite (TObject *Sender,TCustomWinSocket *Socket);
}

Потом создай экземпляр и от ентого экземпляра присвой метод в обработчик события
... << RSDN@Home 1.0 alpha 12 РУЛИТ!!!>>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Re[2]: Сервер без формы
От: Fantasist  
Дата: 07.11.02 22:55
Оценка:
Здравствуйте Hacker_Delphi, Вы писали:

HD>Потом создай экземпляр и от ентого экземпляра присвой метод в обработчик события


HD>


Ну это как-бы очевидно, и не так интересно. То есть мне не так интересно, а интересно мне есть ли в Builder'e такая спецификация, как TMethod в Delphi? closure то они ввели, чтобы не пойти и дальше?
Кстати, кстати. Почему в стандарте такой штуки нет? Ах, да, невозможность проверки типов. Но для объектов унаследованных от TObject такую весч впринципе могли бы сделать.
Re[3]: Сервер без формы
От: Hacker_Delphi Россия  
Дата: 07.11.02 23:13
Оценка:
Здравствуйте Fantasist, Вы писали:
F> Ну это как-бы очевидно, и не так интересно. То есть мне не так интересно, а интересно мне есть ли в Builder'e такая спецификация, как TMethod в Delphi? closure то они ввели, чтобы не пойти и дальше?
F>Кстати, кстати. Почему в стандарте такой штуки нет? Ах, да, невозможность проверки типов. Но для объектов унаследованных от TObject такую весч впринципе могли бы сделать.
Какой TMethod? не помню, если честно — напомни, а?
а про твои приколы с кастом типов — можно, конечно, но вот ты точно знаеш, где в указателе ссылка на объект, а гед — на метод? если да — то легко и непринужденно можно сделать раздергивание их как надо.
а по-поводу присвоения — при _closure в EAX кидается this, а с EDX начинаются параметры. в не _closure параметры ьначинаются с EAX. Кароче, при вызове _closure метода происходит внесение еще одного первого параметра, который равен this
... << RSDN@Home 1.0 alpha 12 РУЛИТ!!!>>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Re[4]: Сервер без формы
От: Fantasist  
Дата: 07.11.02 23:39
Оценка:
Здравствуйте Hacker_Delphi, Вы писали:

HD>а про твои приколы с кастом типов — можно, конечно, но вот ты точно знаеш, где в указателе ссылка на объект, а гед — на метод? если да — то легко и непринужденно можно сделать раздергивание их как надо.

HD>а по-поводу присвоения — при _closure в EAX кидается this, а с EDX начинаются параметры. в не _closure параметры ьначинаются с EAX. Кароче, при вызове _closure метода происходит внесение еще одного первого параметра, который равен this

Это все понятно — не в этом вопрос. А вопрос поясняю ответом на:

HD>Какой TMethod? не помню, если честно — напомни, а?


Это, так сказать, культурное представление указателя на метод. Выглядит так:

  TMethod = record
    Code, Data: Pointer;
  end;

Обявление в Delphi типа:
  TNotifyEvent=procedure of Object;

Фактически эквивалентно
  TNotifyEvent=TMethod;


То есть далее имея

  fOnClick:TNotifyEvent;


Фактически имеем восмибайтовую структуру с указателем на объект и на код. То есть, если мы делаем:

 TMyObject=class
   procedure ClickHandler;
 end;
.....
  fOnClick:=MyObject.ClickHandler;


то имеем:

  TMethod(fOnClick).Code=@ClickHandler;
  TMethod(fOnClick).Data=MyObject;
Re[2]: Сервер без формы
От: k_artem  
Дата: 08.11.02 12:48
Оценка:
Здравствуйте Fantasist

Я сделал так, как вы писали, но ничего не выходит:

[C++ Error] Unit1.cpp(18): E2034 Cannot convert 'void (_fastcall *)(TObject *,TCustomWinSocket *)' to 'void (_fastcall * (_closure )(TObject *,TCustomWinSocket *))(TObject *,TCustomWinSocket *)'

Я пытался преобразовать его и в TSocketNotifyEvent, но все время ошибки
Re[3]: Сервер без формы
От: Fantasist  
Дата: 08.11.02 15:16
Оценка:
Здравствуйте k_artem, Вы писали:

KA>Я сделал так, как вы писали, но ничего не выходит:


А вы проверте, вначале, существует ли такая структура в Builder как TMethod.Легко можно найти если сделать поиск в файлах в исходниках VCL, или объявив переменную TMethod p; удерживая Ctrl кликнуть мышкой, или просто нажав F1, но в этом случае, если она есть, мы не узнаем как она выглядит.
Если такая вещь есть — посмотрите как она объявлена, если нет — придется делать как указал Hacker_Delphi выше: через метод объекта.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.