C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Вызов функции по ссылке
mik_81
Отправлено: 09.02.2005, 19:00


Ученик-кочегар

Группа: Участник
Сообщений: 6



Help!!!!!
Что- то я вконец запутался. Итого имеем
1. Класс- наследник от tthread. Конструктор:
CODE

__fastcall m_thread(bool CreateSuspended,AnsiString sour_path,
               AnsiString dest_path,AnsiString ftp_arh, int f_size,
               bool (*)(int,AnsiString,AnsiString,int,AnsiString),int mode);

2. Функцию
CODE
bool TForm1::fire_log_event(int event,AnsiString descr,AnsiString f_name,
       int f_size,AnsiString remote_addr)

3. Пытаюсь обявить
CODE
m_thread *m_thr=new m_thread(false,ftp_sour_path,ftp_dest_path,
               ftp_arh, allow_f_size,fire_log_event,1);


В ответ получаю:
CODE
[C++ Error] test_serv.cpp(120): E2285 Could not find a match for 'm_thread::m_thread(bool,AnsiString,AnsiString,AnsiString,int,void,int)'

Ткните плиз в в гиблое место.
Konstantine
Отправлено: 09.02.2005, 19:15


Мастер участка

Группа: Модератор
Сообщений: 545



точно не знаю (не проверял), но вроде нада примерно так:
CODE
m_thread *m_thr=new m_thread(false,ftp_sour_path,ftp_dest_path,
              ftp_arh, allow_f_size,this->fire_log_event,1);
Asher
Отправлено: 09.02.2005, 19:29


Мастер участка

Группа: Модератор
Сообщений: 550



Привет.
Не проверял пока, но по логике должно быть
CODE

m_thread *m_thr=new m_thread(false,ftp_sour_path,ftp_dest_path,
              ftp_arh, allow_f_size, &TForm1::fire_log_event,1);

Почитать можно у Страуструпа 15.5. Указатели на члены
mik_81
Отправлено: 10.02.2005, 10:18


Ученик-кочегар

Группа: Участник
Сообщений: 6



2Konstantine так не катит
2Asher А кроме Страуструпа нигде не встречал? А то неохото из-за одной ссылки книгу покупать. А во введении такого нет.
В принципе работает если функцию fire_log_event вынести за пределы класса TForm1, но надо бы внутри.
mik_81
Отправлено: 10.02.2005, 10:23


Ученик-кочегар

Группа: Участник
Сообщений: 6



2Asher:
QUOTE
m_thread *m_thr=new m_thread(false,ftp_sour_path,ftp_dest_path,
             ftp_arh, allow_f_size, &TForm1::fire_log_event,1);

Уже ближе но все равно не видит:
CODE
E2285 Could not find a match for 'm_thread::m_thread(bool,AnsiString,AnsiString,AnsiString,int,bool (TForm1::*)(int,AnsiString,AnsiString,int,AnsiString),int)'
Konstantine
Отправлено: 10.02.2005, 11:04


Мастер участка

Группа: Модератор
Сообщений: 545



ну тогда конструктор так построй:
CODE
_fastcall m_thread(bool CreateSuspended,AnsiString sour_path,
AnsiString dest_path,AnsiString ftp_arh, int f_size,
bool (TForm1::*)(int,AnsiString,AnsiString,int,AnsiString),int mode);
Asher
Отправлено: 10.02.2005, 11:28


Мастер участка

Группа: Модератор
Сообщений: 550



Вот пример навскидку
CODE

class A{
void F(void);
static void S(void);
};

typedef void(A::*ptrF)();//Указатель на функцию-член
typedef void (*ptrS)();//Указатель на статическую функцию-член
A* pA = new A();
ptrF pF = &A::F;
ptrS pS = &A::S;
//ptrF pE = &A::S;//А так неправильно.
pA->F();//Прямой вызов
(pA->*pF)();//Вызов через указатель на член.
pA->S();//Прямой вызов
(pA->*pS)();//Вызов через указатель на член.

соответственно чтобы работало в свой класс Вам нужно передать указатель на экземпляр TForm1, для которого будет осуществлятся вызов функции
AVC
Отправлено: 10.02.2005, 12:00


Ветеран

Группа: Модератор
Сообщений: 1583



Тяжелое наследие Pascal
Так компилится без ошибок
CODE

// h
typedef bool __fastcall (__closure *VCLFun)(int,AnsiString,AnsiString,int,AnsiString);
typedef bool (__fastcall *NatFun)(int,AnsiString,AnsiString,int,AnsiString);

class m_thread : public TThread
{
public:
__fastcall m_thread (bool,AnsiString,AnsiString,AnsiString,int, NatFun, int);
__fastcall m_thread (bool,AnsiString,AnsiString,AnsiString,int, VCLFun, int);

void __fastcall DoTerminate(void){};
void __fastcall Execute (void){};
};

// cpp
//вызвать метод как обычную функцию
void __fastcall TForm1::Test (void)
{
VCLFun vclfun = &fire_log_event;
TMethod Method = *(TMethod*)&vclfun;

NatFun fun = (NatFun)Method.Code;

AnsiString estr = "";
m_thread *m_thr0 = new m_thread(false,estr,estr,estr,0,fun,   1);
m_thread *m_thr1 = new m_thread(false,estr,estr,estr,0,vclfun,1);
}


Знания подчерпнуты из статьи Вячеслава Ермолаева Манипуляции с методами классов, или как вызвать функцию по ее символьному имени.
mik_81
Отправлено: 10.02.2005, 13:13


Ученик-кочегар

Группа: Участник
Сообщений: 6



QUOTE
соответственно чтобы работало в свой класс Вам нужно передать указатель на экземпляр TForm1, для которого будет осуществлятся вызов функции

В принципе как раз от этого и хотел избавится — не передавать ссылку на экзмпляр, а только на интересующий меня метод.
QUOTE
ну тогда конструктор так построй:

Построил. Но так не могу вызвать функцию:
CODE
__fastcall m_thread::m_thread(bool CreateSuspended,AnsiString sour_path,
       AnsiString dest_path,AnsiString ftp_arh, int f_size,
       bool (TForm1::*log_func)(int event,AnsiString descr,AnsiString f_name,
       int f_size,AnsiString remote_addr),int mode)
       : TThread(CreateSuspended)
{
(*log_func)(4,"","","","");}

Получаю
CODE
E2069 Illegal use of member pointer
Asher
Отправлено: 10.02.2005, 13:38


Мастер участка

Группа: Модератор
Сообщений: 550



Избавится от передачи ссылки на экземпляр можно только одним способом — использовать __closure. Он это сделает за Вас неявно biggrin.gif
Если Указатель не нужен — объявите функцию как статик, иначе по любому прийдется указывать или как отдельный параметр, или как ObjName-> перед именем функции. (в примере я исходил из того, что создание m_thr происходит внутри класса TForm1, поэтому this->)
CODE

typedef bool  (__closure *MTFireEvent)( int event, AnsiString descr,AnsiString f_name,  int f_size, AnsiString remote_addr);

__fastcall m_thread(bool CreateSuspended,AnsiString sour_path,
              AnsiString dest_path,AnsiString ftp_arh, int f_size,
              MTFireEvent OnFireEvent_, int mode);

m_thread *m_thr=new m_thread(false,ftp_sour_path,ftp_dest_path,
              ftp_arh, allow_f_size, this->fire_log_event, 1);
mik_81
Отправлено: 13.02.2005, 16:38


Ученик-кочегар

Группа: Участник
Сообщений: 6



QUOTE

CODE  

typedef bool  (__closure *MTFireEvent)( int event, AnsiString descr,AnsiString f_name,  int f_size, AnsiString remote_addr);

__fastcall m_thread(bool CreateSuspended,AnsiString sour_path,
             AnsiString dest_path,AnsiString ftp_arh, int f_size,
             MTFireEvent OnFireEvent_, int mode);

m_thread *m_thr=new m_thread(false,ftp_sour_path,ftp_dest_path,
             ftp_arh, allow_f_size, this->fire_log_event, 1);


То что надо. Сабж закрыт. Спасибо всем откликнувшимся. biggrin.gif

Вернуться в Вопросы программирования в C++Builder