указатель на метод класса
От: Аноним  
Дата: 30.10.07 12:45
Оценка:
Добрый день.
есть класс с методом и указатель.

DWORD WINAPI Threadproc(LPVOID tcp_servers);
typedef  DWORD(CConnectionMeneger::*PMethode)(LPVOID);

так вот хочу получить указатель на метод Threadproc и передать в

PMethode methode = &CConnectionMeneger::Threadproc;
CreateThread(NULL,NULL,methode ,&my_sock,0,&thID);


но получаю error.

error C2440: 'initializing' : cannot convert from 'DWORD (__stdcall CConnectionMeneger::* )(LPVOID)' to 'CConnectionMeneger::PMethode'

как исправить?
или не как?
Re: указатель на метод класса
От: Кодт Россия  
Дата: 30.10.07 13:38
Оценка: +1 :)
Здравствуйте, <Аноним>, Вы писали:

А>как исправить?


Поиском! Исключительно поиском!
Это настолько избитый вопрос, что прямо тоску навевает на старожилов.
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
Re: указатель на метод класса
От: VanG  
Дата: 30.10.07 13:40
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Добрый день.

А>есть класс с методом и указатель.

А>
А>DWORD WINAPI Threadproc(LPVOID tcp_servers);
А>typedef  DWORD(CConnectionMeneger::*PMethode)(LPVOID);
А>

А>так вот хочу получить указатель на метод Threadproc и передать в

А>
А>PMethode methode = &CConnectionMeneger::Threadproc;
А>CreateThread(NULL,NULL,methode ,&my_sock,0,&thID);
А>


А>но получаю error.


А>
А>error C2440: 'initializing' : cannot convert from 'DWORD (__stdcall CConnectionMeneger::* )(LPVOID)' to 'CConnectionMeneger::PMethode'
А>

А>как исправить?
А>или не как?

Объяви Threadproc как static (мой компилятор ругается, если я объявляю тип возвращаемого значения DWORD):

static UINT WINAPI Threadproc(LPVOID tcp_servers);
Re[2]: указатель на метод класса
От: Аноним  
Дата: 30.10.07 13:55
Оценка:
зделал вот так но мне ненравится изврат какой то.

typedef  DWORD(CConnectionMeneger::*PMethode)(LPVOID);
PMethode methode = reinterpret_cast<PMethode>(&CConnectionMeneger::Threadproc);
CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)&methode,&my_sock,0,&thID);

может поправите?
Re[3]: указатель на метод класса
От: VanG  
Дата: 30.10.07 14:05
Оценка:
Здравствуйте, Аноним, Вы писали:

А>зделал вот так но мне ненравится изврат какой то.


А>
А>typedef  DWORD(CConnectionMeneger::*PMethode)(LPVOID);
А>PMethode methode = reinterpret_cast<PMethode>(&CConnectionMeneger::Threadproc);
А>CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)&methode,&my_sock,0,&thID);
А>

А>может поправите?

Я обычно пишу по-другому, то, как вы написали, мне не понятно

class CConnectionManager
{
  ...
  static UINT WINAPI Threadproc( LPVOID tcp_servers );
  ...
};


Важное замечание! для создания нового потока используйте _beginthreadex! Эта функция вызывает внутри себя CreateThread(), но помимо этого делает допольнительные вещи, которых не делает CreateThread()
::beginthreadex( NULL, 0, Threadproc, &my_sock, 0, &thID );
Re[3]: указатель на метод класса
От: rg45 СССР  
Дата: 30.10.07 14:24
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>зделал вот так но мне ненравится изврат какой то.


А>
А>typedef  DWORD(CConnectionMeneger::*PMethode)(LPVOID);
А>PMethode methode = reinterpret_cast<PMethode>(&CConnectionMeneger::Threadproc);
А>CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)&methode,&my_sock,0,&thID);
А>

А>может поправите?

Тема действительно избитая донельзя. Подумай сам: переменная methode имеет тип указателя на нестатическую функцию-член класса. Т.е. для вызова этой функции необходим экземпляр объекта класса CConnectionMeneger. Откуда по-твоему возьмется этот экземпляр в потрохах функции CreateThread? Так ведь этого мало, ты же в CreateThread пытаешься передать указатель на переменную (выделено), в которой хранится указатель на метод.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: указатель на метод класса
От: frogkiller Россия  
Дата: 30.10.07 14:33
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>зделал вот так но мне ненравится изврат какой то.


А>
А>typedef  DWORD(CConnectionMeneger::*PMethode)(LPVOID);
А>PMethode methode = reinterpret_cast<PMethode>(&CConnectionMeneger::Threadproc);
А>CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)&methode,&my_sock,0,&thID);
А>

А>может поправите?

1. reinterpret_cast в данном случае не нужен вообще. У тебя же прекрасно работает
PMethode methode = &CConnectionMeneger::Threadproc;

2. Основная фигня в этой строчке
 CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)&methode,&my_sock,0,&thID);

Ты просто заставил заткнуться компилятор, передав указатель на указатель на метод, приведя к тому, что хочет получить функция. Ты хочешь вызывать его как-то так:
(lpParameter->(*(PMethode*)lpStartAddress))(lpParameter)
?
Иногда это может сработать. Но не всегда. Беда в том, что PMethode может иметь размер больше, чем LPTHREAD_START_ROUTINE, и в результате ты (или кто захочет воспользоваться твоим классом и унаследует от него свой класс) словишь AV в самом неожиданном месте. Это может происходить в частности при множественном и виртуальном наследовании. Посмотри, например, что делают
#pragma pointers_to_members(full_generality, virtual_inheritance)

в MSVC.

Кстати, посмотри лучше на _begintreadex вместо CreateThread.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Курица — это инструмент, с помощью которого одно яйцо производит другие.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.