информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Атака на InternetЗа кого нас держат?Страшный баг в Windows
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Очередное исследование 19 миллиардов... 
 Оптимизация ввода-вывода как инструмент... 
 Зловреды выбирают Lisp и Delphi 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
если вы видите этот текст, отключите в настройках форума использование JavaScript
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
[C++] проверенное решение 02.02.03 18:29  Число просмотров: 1158
Автор: amirul <Serge> Статус: The Elderman
<"чистая" ссылка>
> > А вообще, я не знаю почему, но у меня тоже не
> получалость
> > функции-член класса вызвать отдельной нитью. Но если
> > функцию определить независимо то все работает
> (проверено).
> Ну вообще-то ничего удивительного :) "Внешний вид"
> указателя на функцию и указателя на член класса отличается
Внешний вид в первую очередь отличается на соглашение о вызове: thiscall, а для глобальных - __stdcall для большинства WinAPI. В thiscall - неявно передается указатель this (для VC - в регистре ecx), и обращение к членам происходит именно через него, а все остальные параметры передаются как __cdecl.
А stdcall - это по мойму паскалевское соглашение, где параметры передаются через стек, а место из под них освобождает вызванная функция, в отличие от cdecl-а, где стек очищает вызывающая функция и именно это дает возможность использования переменного числа аргументов.

Короче, не thiscall-ом функция-член может быть только если объявить ее static - тогда она вызывается в контексте какого-либо класса вообще, а не конкретного объекта этого класса. Такую функцию можно передать и в качестве колбяки и в качестве нитеобразующей и вообще (надо только не забыть переопределить соглашение на __stdcall)

> примерно на имя класса и два двоеточия :) Другими словами,
> это просто разные типы указателей, и друг к другу они на
> халяву не приводятся.
<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, все должно заработать.
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2025 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach