Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| |
[Win32] Боюсь, что понятно не совсем 30.01.03 17:22 Число просмотров: 1047
Автор: Ktirf <Æ Rusakov> Статус: Elderman
|
При использовании нитепорождающих функций WinAPI нужно, чтобы нитевая функция не была членом класса, либо была статическим членом класса. Я обращаю на это внимание, исходя из запостенного сообщения об ошибке. На всякий случай уточнил, потому что предыдущий автор привел довольно большой кусок кода, не сразу ясно где рыть.
|
<programming>
|
Продолжая про Netbios. Вопрос начинающего по потокам. 29.01.03 17:50
Автор: Step <Step Alex> Статус: Member
|
Вот хотел я загнать этот код в процесс, а не получается. Не пойму что делать. Вроде все как в MSDN-не сделал, а он меня посылает.
Итак код, который проверяет запросы я загнал в функцию и хочу, чтобы она шла отдельным потоком.
hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0,&threadID );
функция описана так
unsigned __stdcall CnetBDlg::SecondThreadFunc(void* pArguments )
{
while(1)
{
// здесь код от PS про NetBIOS
}
}
но компилятор сопротивляется
netBDlg.cpp(294): error C2276: '&' : illegal operation on bound member function expression
Подскажите в чем дело или просто наведите - как правильно организовать отдельный процесс, что-бы приложение не висло пока занимается всякой интересностью.
|
|
проверенное решение 02.02.03 04:47
Автор: vh <Дмитрий> Статус: Member Отредактировано 02.02.03 04:50 Количество правок: 1
|
&SecondThreadFunc
ну понятно что здесь не нужен &
А вообще, я не знаю почему, но у меня тоже не получалость функции-член класса вызвать отдельной нитью. Но если функцию определить независимо то все работает (проверено). Поэтому я просто сделал маленькую функцию отдельно, которая и запускает член класса:
unsigned __stdcall thread(LPVOID pParam)
{
theApp.showmes((char *)pParam);
}
void CNettest7App::StartIt(char *str)
{
_beginthreadex(
NULL,
0,
thread,
(void *) str,
0,
NULL);
}
// не забудь включить process.h
либо с помощью API:
DWORD WINAPI thread(LPVOID pParam)
{
theApp.showmes((char *)pParam);
}
void CNettest7App::StartIt(char *str)
{
hThread = ::CreateThread(
NULL,
0,
thread,
(LPVOID) str,
0,
NULL);
}
А можно узнать чем ты занимешься с NetBios. Дело в том что сейчас я как раз занимаюсь им же, и тоже интересовался не далее как на днях потоками :)
|
| |
проверенное решение -маленький вопросик 03.02.03 12:28
Автор: Step <Step Alex> Статус: Member
|
> unsigned __stdcall thread(LPVOID pParam) > { > theApp.showmes((char *)pParam); > } >
Вот здесь то и возникает маленький вопросик. Дело в том, что у меня все выполняет класс диалогового окна и theApp не имеет такой функции (по скольку она описана в классе диалога).
:-))) поробовал theDlg......такого нету..
Как бы мне получить в "сторонию" функцию указатель на существующий класс диалога. т.е. который уже инициализировался.
(камнями просьба не бросаться, я тока учусь :-))))))
|
| | |
попробуй это... 03.02.03 18:48
Автор: vh <Дмитрий> Статус: Member
|
> Вот здесь то и возникает маленький вопросик. Дело в том, > что у меня все выполняет класс диалогового окна и theApp > не имеет такой функции (по скольку она описана в классе > диалога). > > :-))) поробовал theDlg......такого нету.. > Как бы мне получить в "сторонию" функцию указатель на > существующий класс диалога. т.е. который уже > инициализировался. > > (камнями просьба не бросаться, я тока учусь :-))))))
CTestDlg *dlg = theApp.m_pMainWnd;
dlg->func(); // soul brother :)
не знаю правда насколько это хорошо (т.е. наверное обычно делают по другому)...позже посмотрю еще в книжке Круглински
|
| | |
Указателей на класс не бывает, бывают указатели на объекты класса :-))) 03.02.03 15:34
Автор: amirul <Serge> Статус: The Elderman
|
> > unsigned __stdcall thread(LPVOID pParam) > > { > > theApp.showmes((char *)pParam); > > } > > > > Вот здесь то и возникает маленький вопросик. Дело в том, > что у меня все выполняет класс диалогового окна и theApp > не имеет такой функции (по скольку она описана в классе > диалога). Конкретно скажи какой тип имеет theApp (если CWinApp, то откуда там showmes, и что оно делает)
> :-))) поробовал theDlg......такого нету.. > Как бы мне получить в "сторонию" функцию указатель на > существующий класс диалога. т.е. который уже > инициализировался. А здесь конкретно скажи указатель на что тебе нужен. Если я правильно понял, то в MFC Class Wizard-е можно задать имя переменной, по которой можно будет потом обращаться к некоторому объекту (в данном случае диалогу). Вписывай туда theDlg и все. Только все равно не понял, что тебе нужно.
> (камнями просьба не бросаться, я тока учусь :-))))))
|
| | |
проверенное решение -маленький вопросик 03.02.03 15:32
Автор: Ktirf <Æ Rusakov> Статус: Elderman
|
> Как бы мне получить в "сторонию" функцию указатель на > существующий класс диалога. т.е. который уже > инициализировался. Ты можешь передать указатель на диалог в нитевую функцию (я так понимаю, дело в этом). Там в нитепорождающих функциях есть такой интересный указатель на void после указателя на нитевую функцию. Через это ушко иголки можно протащить указатель на все, на что можно указывать :) А в самой нитевой функции приводишь void * обратно к класс_диалога * и пользуешься :) Но имей в виду, что этооченьопасное занятие, потому что класс Dialog не рассчитан на многонитевую работу. Честно говоря, я сейчас точно не помню, как, но можно сделать это более аккуратно, чтобы все было в порядке (search MSDN). Но общий принцип такой.
> (камнями просьба не бросаться, я тока учусь :-)))))) Нормально, я сам такими вопросами задавался, когда учился :)
|
| |
Да в общем. 03.02.03 11:07
Автор: Step <Step Alex> Статус: Member
|
> А можно узнать чем ты занимешься с NetBios. Дело в том что > сейчас я как раз занимаюсь им же, и тоже интересовался не > далее как на днях потоками :)
Просто осваиваю СРР.... а так как лучший способ научиться - пробовать что то конкретное, я в связи со своей специальностью (администрирование) пробую сделать небольшие програмки связанные с сетевыми решениями (как то с утра предложения не строятся :-) ) . Делать примеры из книжек мне не очень интересно, так как мне не надо учиться программировать (как "строить" программы я вроде знаю, институт и последующие работы, паскаль, VB и т.п.).
А так как, если приложение не консольное, а программа постоянно выполняется, без потоков никуда. Она просто отвисает. Это я понял когда делал порт-сканер. Но его делал на C# . Попробовав и то и это понял, что CPP все таки более интересен (в основном из-за своей независимости).
Сегодня как освобожусь попробую этот способ.....
Всем спасибо за помощь.
|
| |
[C++] проверенное решение 02.02.03 11:10
Автор: Ktirf <Æ Rusakov> Статус: Elderman
|
> А вообще, я не знаю почему, но у меня тоже не получалость > функции-член класса вызвать отдельной нитью. Но если > функцию определить независимо то все работает (проверено). Ну вообще-то ничего удивительного :) "Внешний вид" указателя на функцию и указателя на член класса отличается примерно на имя класса и два двоеточия :) Другими словами, это просто разные типы указателей, и друг к другу они на халяву не приводятся.
|
| | |
[C++] проверенное решение 02.02.03 18:29
Автор: amirul <Serge> Статус: The Elderman
|
> > А вообще, я не знаю почему, но у меня тоже не > получалость > > функции-член класса вызвать отдельной нитью. Но если > > функцию определить независимо то все работает > (проверено). > Ну вообще-то ничего удивительного :) "Внешний вид" > указателя на функцию и указателя на член класса отличается Внешний вид в первую очередь отличается на соглашение о вызове: thiscall, а для глобальных - __stdcall для большинства WinAPI. В thiscall - неявно передается указатель this (для VC - в регистре ecx), и обращение к членам происходит именно через него, а все остальные параметры передаются как __cdecl.
А stdcall - это по мойму паскалевское соглашение, где параметры передаются через стек, а место из под них освобождает вызванная функция, в отличие от cdecl-а, где стек очищает вызывающая функция и именно это дает возможность использования переменного числа аргументов.
Короче, не thiscall-ом функция-член может быть только если объявить ее static - тогда она вызывается в контексте какого-либо класса вообще, а не конкретного объекта этого класса. Такую функцию можно передать и в качестве колбяки и в качестве нитеобразующей и вообще (надо только не забыть переопределить соглашение на __stdcall)
> примерно на имя класса и два двоеточия :) Другими словами, > это просто разные типы указателей, и друг к другу они на > халяву не приводятся.
|
|
Стыдно 29.01.03 17:57
Автор: PS <PS> Статус: Elderman
|
Во первых: компилятор тебе сам сказал, что ему не нравится.
Во вторых: на этом форуме несколько раз поднималась похожая тема.
Вот тебе кусок кода:
void CSniffer::Start()
{
WaitForSingleObject( m_stop_mutex, INFINITE );
m_stop = false;
ReleaseMutex( m_stop_mutex );
_beginthread( WorkingThread, 0, this );
}
void CSniffer::WorkingThread( void* _me )
{
bool stop;
CSniffer* me = (CSniffer*)_me;
SOCKET sock = socket( AF_INET, SOCK_RAW, IPPROTO_RAW );
if( sock == INVALID_SOCKET )
{
WaitForSingleObject( me->m_stop_mutex, INFINITE );
me->m_stop = true;
---
class CSniffer
{
public:
.....................
protected:
............
static void WorkingThread( void* );
};
---
Понятно ?
|
| |
[Win32] Боюсь, что понятно не совсем 30.01.03 17:22
Автор: Ktirf <Æ Rusakov> Статус: Elderman
|
При использовании нитепорождающих функций WinAPI нужно, чтобы нитевая функция не была членом класса, либо была статическим членом класса. Я обращаю на это внимание, исходя из запостенного сообщения об ошибке. На всякий случай уточнил, потому что предыдущий автор привел довольно большой кусок кода, не сразу ясно где рыть.
|
| | |
[Win32] Боюсь, что понятно не совсем 30.01.03 17:37
Автор: Step <Step Alex> Статус: Member
|
Вот и у меня........ уже туплю по полной программе......
netBDlg.cpp(230): error C2664: '_beginthread' : cannot convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)'
None of the functions with this name in scope match the target type
Вот код
это вызов
_beginthread( SecondThreadFunc, 0, this );
это функция
void CnetBDlg::SecondThreadFunc(void* _me )
{
CnetBDlg* me = (CnetBDlg*)_me;
while(1)
{.......................
|
| | | |
[Win32] Боюсь, что понятно не совсем 30.01.03 18:17
Автор: Ktirf <Æ Rusakov> Статус: Elderman
|
> netBDlg.cpp(230): error C2664: '_beginthread' : cannot > convert parameter 1 from 'void (void *)' to 'void (__cdecl *)(void *)' > None of the functions with this name in scope match the target type > > Вот код > > это вызов > _beginthread( SecondThreadFunc, 0, this ); > > это функция > > void CnetBDlg::SecondThreadFunc(void* _me )
Ну собственно в сообщении об ошибке все сказано: сигнатура функции не подходит. Объяви SecondThreadFunc с __cdecl, все должно заработать.
|
|
|