Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Visual C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.03.2016, 14:14   #1
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
Вопрос Указатели в статической функции

Доброго времени суток.
Сижу разбираюсь с libevent. Создал класс NETWORK для использования этой библиотеки. В классе все функции статичные. Пытаюсь в класс передать указатель на массив структур для подключений, но в статичных функциях класса не могу с ними работать:

h файл:
Код:
class NETWORK
{
public:
	NETWORK(int port, sAccounts* accs);
	~NETWORK();
	void run();

private:
	sAccounts*		all_acc;


	struct event_base		*base;
	struct evconnlistener	*listener;
	static void accept_error_cb(struct evconnlistener *listener, void *arg);
	static void accept_connection_cb(struct evconnlistener *listener,
		evutil_socket_t fd, struct sockaddr *addr, int sock_len,
		void *arg);
	static void echo_event_cb(struct bufferevent *buf_ev, short events, void *arg);
	static void echo_read_cb(struct bufferevent *buf_ev, void *arg);
	static void echo_write_cb(struct bufferevent *buf_ev, void *arg);
	

};
cpp:
Код:
NETWORK::NETWORK(int port, sAccounts* accs)
{
	all_acc = accs;

....

void NETWORK::accept_connection_cb(struct evconnlistener *listener,
	evutil_socket_t fd, struct sockaddr *addr, int sock_len,
	void *arg)
{
	/* При обработке запроса нового соединения необходимо создать для него
	объект bufferevent */
	struct event_base *base = evconnlistener_get_base(listener);
	struct bufferevent *buf_ev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);

	for (int i = 0; i < _MAX_CLIENTS; i++)
	{
		all_acc[i].isUse = false;
	}

	bufferevent_setcb(buf_ev, echo_read_cb, NULL, echo_event_cb, NULL);
	bufferevent_enable(buf_ev, (EV_READ | EV_WRITE));
}
Ошибка:
Error 4 error C2109: subscript requires array or pointer type .\network\network.cpp 90 1 ServerList
Error 5 error C2228: left of '.isUse' must have class/struct/union .\network\network.cpp
Error 2 error C2597: illegal reference to non-static member 'NETWORK::all_acc' .\network\network.cpp
Error 3 error C3867: 'NETWORK::all_acc': function call missing argument list; use '&NETWORK::all_acc' to create a pointer to member .\network\network.cpp
6 IntelliSense: a nonstatic member reference must be relative to a specific object .\network\network.cpp 90 13 ServerList

Последний раз редактировалось Tahoma; 05.03.2016 в 14:22.
Tahoma вне форума Ответить с цитированием
Старый 05.03.2016, 14:23   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Из статики так нельзя обращаться к нестатике... Не знаю, что вы хотите, но либо массив тоже делайте статикой, либо функции нестатикой, либо трюк со статическим this
p51x вне форума Ответить с цитированием
Старый 05.03.2016, 14:31   #3
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Из статики так нельзя обращаться к нестатике... Не знаю, что вы хотите, но либо массив тоже делайте статикой, либо функции нестатикой, либо трюк со статическим this
Функцию я не могу сделать не статической. libevent перестает работать. Можете пример привести? Буду очень благодарен.
Tahoma вне форума Ответить с цитированием
Старый 05.03.2016, 16:34   #4
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,709
По умолчанию

Цитата:
Функцию я не могу сделать не статической. libevent перестает работать.
Может вы просто не умееете первый параметр байндить?

Пример чего вам нужен?
p51x вне форума Ответить с цитированием
Старый 06.03.2016, 09:30   #5
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Может вы просто не умееете первый параметр байндить?

Пример чего вам нужен?
Можно как-нибудь из статической функции запустить обычную, чтобы могла работать с массивами и указателями? Что то у гуглу не могу объяснить, что я от него хочу.

Вот нашел пример реализации без статики: https://github.com/jasonish/libevent.../chat-server.c
Буду ковырять.

Последний раз редактировалось Tahoma; 06.03.2016 в 09:44.
Tahoma вне форума Ответить с цитированием
Старый 06.03.2016, 10:26   #6
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Цитата:
Сообщение от Tahoma Посмотреть сообщение
Можно как-нибудь из статической функции запустить обычную
Прочитайте для чего служит последний параметр функции (например) bufferevent_setcb а также последний параметр у callback функций.
waleri вне форума Ответить с цитированием
Старый 06.03.2016, 12:29   #7
Tahoma
DI HALT RET
Форумчанин
 
Аватар для Tahoma
 
Регистрация: 30.12.2010
Сообщений: 117
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Прочитайте для чего служит последний параметр функции (например) bufferevent_setcb а также последний параметр у callback функций.
Да, все оказалось элементарно просто (когда сделал уже ))) ).
Вот что у меня получилось:

*.h:
Код:
void real_acceptcb(struct evconnlistener *listener,
		evutil_socket_t fd, struct sockaddr *addr, int sock_len);
static void accept_connection_cb(struct evconnlistener *listener,
		evutil_socket_t fd, struct sockaddr *addr, int sock_len,
		void *arg);
*.cpp:
Код:
...
listener = evconnlistener_new_bind(base, accept_connection_cb, this,
		(LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE), -1, (struct sockaddr *)&sin, sizeof(sin));
...

void NETWORK::real_acceptcb(struct evconnlistener *listener,
	evutil_socket_t fd, struct sockaddr *addr, int sock_len)
{
	struct event_base *base = evconnlistener_get_base(listener);
	struct bufferevent *buf_ev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);

	for (int i = 0; i < _MAX_CLIENTS; i++)
	{
		all_acc[i].isUse = false;
	}

	bufferevent_setcb(buf_ev, echo_read_cb, NULL, echo_event_cb, NULL);
	bufferevent_enable(buf_ev, (EV_READ | EV_WRITE));
}

void NETWORK::accept_connection_cb(struct evconnlistener *listener,
	evutil_socket_t fd, struct sockaddr *addr, int sock_len,
	void *arg)
{
	NETWORK *cl = static_cast<NETWORK *>(arg);
	cl->real_acceptcb(listener, fd, addr, sock_len);
}

Сократил немного, чтобы в CPP файле не мешались статичные функции:
Код:
static void accept_connection_cb(struct evconnlistener *listener,
		evutil_socket_t fd, struct sockaddr *addr, int sock_len,
		void *arg) { ((NETWORK*)arg)->real_acceptcb(listener, fd, addr, sock_len); }

Последний раз редактировалось Tahoma; 06.03.2016 в 12:38.
Tahoma вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Экспорт функции из DLL для дальнейшей статической загрузки в Delphi The SCS Общие вопросы C/C++ 1 01.07.2012 18:28
Указатели на функции (си) Miles Помощь студентам 3 08.01.2012 23:30
Проблема с взаимодействием динамической и статической памяти - обращение к статической переменной Comst95 Паскаль, Turbo Pascal, PascalABC.NET 1 03.01.2012 18:46
Указатели на функции profi Общие вопросы C/C++ 20 12.07.2010 14:11
Функции и Указатели на С++ Wia Помощь студентам 3 17.04.2009 14:57