Проблема заключается в том, что функцию, которую нужно передать в поток, находится в классе, и к сожалению её нельзя обозначить как static
Ниже приведен исходный код:
class MTcp_server
{
private:
bool sock_inited;
bool listening;
char buff [1024];
int clients;
int serv_error;
unsigned id_lstn;
SOCKET serv_socket;
sockaddr_in serv_addr;
unsigned int __stdcall lstn (void*);
public:
int port;
MTcp_server(int);
int out_error ();
void create_sock();
void close_sock();
void blind_serv();
unsigned listen_start(int,void*);
void listen_end (unsigned);
void send (int);
void send (double);
void send (char);
void send (char*);
void send (string);
void send (bool);
unsigned int __stdcall foo (void*);
~MTcp_server();
};
// тут типо конструкторы и прочие функии, которые не какое отношение не имеютunsigned MTcp_server::listen_start(int n, void* indata)
{
if (listening==0)
{
if (listen(serv_socket,n))
{
serv_error=WSAGetLastError();
}
else
{
serv_error=0;
listening=1;
unsigned int id;
_beginthreadex(NULL,0,lstn,indata,0, &id);
return id;
}
}
}
unsigned int __stdcall MTcp_server::lstn (void* indata)
{
MTcp_client_data client;
int client_addr_size=sizeof(client.client_addr);
while (client.client_socket=accept(serv_socket, (sockaddr *) &client.client_addr, &client_addr_size))
{
clients++;
client.hst=gethostbyaddr ((char*)&client.client_addr.sin_addr.s_addr,4,AF_INET);
unsigned clid;
//_beginthreadex(NULL,0,foo,indata,0, &clid); //тут такая же проблема
}
}
// дальше функции и деструктор класса
И вот тут проблема вышла:
H:\codeblocks\4\tststr\..\..\1\Test\Inet.hpp|142|error: argument of type 'unsigned int (MTcp_server:)(void*)' does not match 'unsigned int (*)(void*)'|
Пожайлуста помогите, буду очень благодарен (да если это важную роль сыграет, то компилятор: mingw (gcc 4.6.2))
Здравствуйте, maxis11, Вы писали:
M>Проблема заключается в том, что функцию, которую нужно передать в поток, находится в классе, и к сожалению её нельзя обозначить как static M>Ниже приведен исходный код: M>...
Передавайте в _beginthreadex адрес функции, находящейся в глобальном или анонимном
пространстве имен. А этой функции можно передать указатель на экземпляр класса,
из которого она сможет брать параметры и вызывать методы:
namespace {
unsigned int
_stdcall
ThreadProc(
__in VOID * pParam
)
{
MTcp_server *pServer = (MTcp_server *)pParam;
pServer->lstn();
return 0;
}
} // namespaceunsigned MTcp_server::listen_start(int n, void* indata)
{
if (listening==0)
{
if (listen(serv_socket,n))
{
serv_error=WSAGetLastError();
}
else
{
serv_error=0;
listening=1;
unsigned int id;
// Если потоков несколько, можно придумать
// другую схему для передачи indata.
m_indata = indata;
_beginthreadex(NULL, 0, ThreadProc, this, 0, &id);
return id;
}
}
}
Здравствуйте, okman, Вы писали:
O>Здравствуйте, maxis11, Вы писали:
M>>Проблема заключается в том, что функцию, которую нужно передать в поток, находится в классе, и к сожалению её нельзя обозначить как static M>>Ниже приведен исходный код: M>>...
O>Передавайте в _beginthreadex адрес функции, находящейся в глобальном или анонимном O>пространстве имен. А этой функции можно передать указатель на экземпляр класса, O>из которого она сможет брать параметры и вызывать методы: O>
O>namespace {
O>unsigned int
O>_stdcall
O>ThreadProc(
O> __in VOID * pParam
O> )
O>{
O> MTcp_server *pServer = (MTcp_server *)pParam;
O> pServer->lstn();
O> return 0;
O>}
O>} // namespace
O>unsigned MTcp_server::listen_start(int n, void* indata)
O>{
O> if (listening==0)
O> {
O> if (listen(serv_socket,n))
O> {
O> serv_error=WSAGetLastError();
O> }
O> else
O> {
O> serv_error=0;
O> listening=1;
O> unsigned int id;
O> // Если потоков несколько, можно придумать
O> // другую схему для передачи indata.
O> m_indata = indata;
O> _beginthreadex(NULL, 0, ThreadProc, this, 0, &id);
O> return id;
O> }
O> }
O>}
O>
Здравствуйте, maxis11, Вы писали:
M>Проблема заключается в том, что функцию, которую нужно передать в поток, находится в классе, и к сожалению её нельзя обозначить как static
Как насчёт посмотреть в сторону boost::thread ? Там удобная интеграция с bind и function.
Чтобы не руками писать переходник, как уже посоветовали выше.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, maxis11, Вы писали:
M>>Проблема заключается в том, что функцию, которую нужно передать в поток, находится в классе, и к сожалению её нельзя обозначить как static
К>Как насчёт посмотреть в сторону boost::thread ? Там удобная интеграция с bind и function. К>Чтобы не руками писать переходник, как уже посоветовали выше.
Спасибо, посмотрю, хотя если честно я как то сторонними библиотеками не очень то люблю пользоваться, но если порекомендовали, почему бы и нет...
Здравствуйте, maxis11, Вы писали:
M>Здравствуйте, Кодт, Вы писали:
К>>Здравствуйте, maxis11, Вы писали:
M>>>Проблема заключается в том, что функцию, которую нужно передать в поток, находится в классе, и к сожалению её нельзя обозначить как static
К>>Как насчёт посмотреть в сторону boost::thread ? Там удобная интеграция с bind и function. К>>Чтобы не руками писать переходник, как уже посоветовали выше.
M>Спасибо, посмотрю, хотя если честно я как то сторонними библиотеками не очень то люблю пользоваться, но если порекомендовали, почему бы и нет...
Кстати, boost::bind и boost::function полезны не только из-за интеграции с boost::thread — они хорошо годятся еще например для написания собственных функций перебора, принимающих "делегат" для каждого элемента. Если в сишном стиле это может выглядеть так:
Да и вообще, бывает, что с ними можно писать меньше шаблонного кода (понятно, что нужные делегаты будут генерироваться по шаблону внутри function и bind, но в клиентской программе они точно будут меньше мозолить глаза=)).
Здравствуйте, Warturtle, Вы писали:
W>Здравствуйте, maxis11, Вы писали:
M>>Здравствуйте, Кодт, Вы писали:
К>>>Здравствуйте, maxis11, Вы писали:
M>>>>Проблема заключается в том, что функцию, которую нужно передать в поток, находится в классе, и к сожалению её нельзя обозначить как static
К>>>Как насчёт посмотреть в сторону boost::thread ? Там удобная интеграция с bind и function. К>>>Чтобы не руками писать переходник, как уже посоветовали выше.
M>>Спасибо, посмотрю, хотя если честно я как то сторонними библиотеками не очень то люблю пользоваться, но если порекомендовали, почему бы и нет... W>Кстати, boost::bind и boost::function полезны не только из-за интеграции с boost::thread — они хорошо годятся еще например для написания собственных функций перебора, принимающих "делегат" для каждого элемента. Если в сишном стиле это может выглядеть так: W>
W>Да и вообще, бывает, что с ними можно писать меньше шаблонного кода (понятно, что нужные делегаты будут генерироваться по шаблону внутри function и bind, но в клиентской программе они точно будут меньше мозолить глаза=)).
Всё хорошо, но я никак не могу собрать boost Libraries (1.49) как придумаю, как собрать либы, буду идти от простого к сложному, постепенно добавлять\заменять на более оптимальный вариант, ну всё, всем спасибо большое тему можно закрывать
M>Проблема заключается в том, что функцию, которую нужно передать в поток, находится в классе, и к сожалению её нельзя обозначить как static
Это общепринятое решение. такое же как приведенное okman (через передачу указателя на объект через параметр), но без использования глобальных функций. Если статик функцию нельзя использовать из-за того, что требуется доступ к состоянию определенного объекта, то это то, что надо.