Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> инициализация указателя на функцию 
:(
    Опции темы
GoldFinch
Дата 29.3.2010, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Код

typedef int (*FARPROC)();
FARPROC GetProcAddress()
{
    return 0;
}

int main()
{
    void (*bar)(int);
    (FARPROC&)bar = GetProcAddress();
}

хочется записать объявление и инициализацию bar в 1 строчку

вот такой вариант, хоть и в 1 строчку, но длинный и не красивый
void (*bar)(int) = (void(*)(int))GetProcAddress();
PM MAIL ICQ   Вверх
mes
Дата 29.3.2010, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(GoldFinch @  29.3.2010,  17:30 Найти цитируемый пост)
void (*bar)(int) = (void(*)(int))GetProcAddress(); 

позвольте узнать, чем не подходит такое :
Код

    FARPROC bar = GetProcAddress();


Цитата(GoldFinch @  29.3.2010,  17:30 Найти цитируемый пост)
объявление и инициализацию

придераюсь: объявление (хотя лучше определение) и присвоение smile


Это сообщение отредактировал(а) mes - 29.3.2010, 18:43


--------------------
PM MAIL WWW   Вверх
GoldFinch
Дата 29.3.2010, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



mes, не подходит, т.к. потом при вызове bar мне придется кастовать ее к ее сигнатуре

((void(*)(int))*bar)(100);

Это сообщение отредактировал(а) GoldFinch - 29.3.2010, 18:47
PM MAIL ICQ   Вверх
Earnest
Дата 29.3.2010, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Я всегда объявляю типы для функций:
typedef void (*FDoSomething)(int);

Тогда и объявление и получение выглядят вполне прилично:
FDoSomething bar = (FDoSomething) GetProcAddress();




--------------------
...
PM   Вверх
GoldFinch
Дата 29.3.2010, 19:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Earnest, не хотеть в 2 строчки! хотеть в 1 строчку!

я хочу сделать импортируемые функции глобальными переменными, импортировать их 1 раз,
и по этому мне не нужны отдельно их типы
PM MAIL ICQ   Вверх
mes
Дата 29.3.2010, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(GoldFinch @  29.3.2010,  18:01 Найти цитируемый пост)
я хочу сделать импортируемые функции глобальными переменными, импортировать их 1 раз,
и по этому мне не нужны отдельно их типы 

ну а если сделать шаблонный враппер, имеющий нужные преобразования ?



--------------------
PM MAIL WWW   Вверх
GoldFinch
Дата 29.3.2010, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



счя набросал вот такой кодес, вроде выглядит красиво
Код

//-------------------- test function ------------------------
void test_in_another_module(int)
{
   cout << "test called\n";
}

//----------------- windows.h ---------------------------
typedef int (*FARPROC)();
FARPROC GetProcAddress(const char* /*name*/)
{
    return (FARPROC)&test_in_another_module;
}

//---------------------- my_api_import.h ------------
#include <boost/function.hpp>

template<typename Signature>
struct api_function : boost::function<Signature>
{
   typedef boost::function<Signature> base_t;
   api_function(FARPROC rhs) : base_t((Signature*)rhs) {}
};

//-------------------usage...--------------------------------
int main()
{
   api_function<void(int)>test = GetProcAddress("test");
   test(100);
}


Добавлено через 21 секунду
mes, да)

Добавлено через 2 минуты и 16 секунд
а еще лучше вот так
Код

//---------------------- my_api_import.h ------------
#include <boost/function.hpp>
template<typename Signature>
struct api_function : boost::function<Signature>
{
   typedef boost::function<Signature> base_t;
   api_function(const char* name) 
      : base_t((Signature*)GetProcAddress(name)) 
   {}
};
//-------------------usage...--------------------------------
int main()
{
   api_function<void(int)>test("test");
   test(100);
}

PM MAIL ICQ   Вверх
Earnest
Дата 29.3.2010, 19:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Ну ты капризный...
По-другому (чем ты уже писал) в одну строчку не получится.

Ну можно еще макросами. Т.е. раскрывать будет как у тебя, а в коде будет примерно так:

DECLARE_FUNCTION (void (*)(int), bar, "NameForGetProcAddress")

Так тебе красиво?


--------------------
...
PM   Вверх
GoldFinch
Дата 29.3.2010, 19:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Earnest, не, макросами не красиво
хотя для случаев когда нет (boost|tr1)::function - подойдет
PM MAIL ICQ   Вверх
GoldFinch
Дата 29.3.2010, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



осталось только победить __stdcall  =\
PM MAIL ICQ   Вверх
GoldFinch
Дата 29.3.2010, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



угу, (boost|tr1)::function не поддерживает stdcall, использовать bind который поддерживает stdcall - это малость оверхед, да и сам function - немалый оверхед (~32байта на указатель)

а свои классы выглядят страшно %)
Код

#ifndef API_FUNCTION_H_INCLUDED_
#define API_FUNCTION_H_INCLUDED_

/* Windows API Dynamic Import
 *
 * Example:

api_function<void()> foo("some.dll", "foo");
....
foo();

 *
 */

#include <windows.h>

namespace detail {

template<typename Signature> struct stdcall_function_ptr;

struct stdcall_function_address
{
    typedef void* ptr_t;
    ptr_t ptr;
};

/* ================= stdcall_function_ptr code was generated by following Python script: =============

def num_list(pfx, n): return ', '.join(pfx + str(i) for i in range(n))
def num_pairs(pfx1, pfx2, n): return ', '.join(pfx1 + str(i) + ' ' + pfx2 + str(i) for i in range(n))
for i in range(16): print("""
template<typename R, """ + num_list('typename T', i) + """>
struct stdcall_function_ptr<R(""" + num_list('T', i) + """)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(""" + num_list('T', i) + """);
    R operator() (""" + num_pairs('T', 'a', i) + """) { return (*(fn_t)ptr)(""" + num_list('a', i) + """); }
};""")

*/

template<typename R, >
struct stdcall_function_ptr<R()> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)();
    R operator() () { return (*(fn_t)ptr)(); }
};

template<typename R, typename T0>
struct stdcall_function_ptr<R(T0)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0);
    R operator() (T0 a0) { return (*(fn_t)ptr)(a0); }
};

template<typename R, typename T0, typename T1>
struct stdcall_function_ptr<R(T0, T1)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1);
    R operator() (T0 a0, T1 a1) { return (*(fn_t)ptr)(a0, a1); }
};

template<typename R, typename T0, typename T1, typename T2>
struct stdcall_function_ptr<R(T0, T1, T2)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2);
    R operator() (T0 a0, T1 a1, T2 a2) { return (*(fn_t)ptr)(a0, a1, a2); }
};

template<typename R, typename T0, typename T1, typename T2, typename T3>
struct stdcall_function_ptr<R(T0, T1, T2, T3)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2, T3);
    R operator() (T0 a0, T1 a1, T2 a2, T3 a3) { return (*(fn_t)ptr)(a0, a1, a2, a3); }
};

template<typename R, typename T0, typename T1, typename T2, typename T3, typename T4>
struct stdcall_function_ptr<R(T0, T1, T2, T3, T4)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2, T3, T4);
    R operator() (T0 a0, T1 a1, T2 a2, T3 a3, T4 a4) { return (*(fn_t)ptr)(a0, a1, a2, a3, a4); }
};

template<typename R, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
struct stdcall_function_ptr<R(T0, T1, T2, T3, T4, T5)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2, T3, T4, T5);
    R operator() (T0 a0, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5) { return (*(fn_t)ptr)(a0, a1, a2, a3, a4, a5); }
};

template<typename R, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
struct stdcall_function_ptr<R(T0, T1, T2, T3, T4, T5, T6)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2, T3, T4, T5, T6);
    R operator() (T0 a0, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6) { return (*(fn_t)ptr)(a0, a1, a2, a3, a4, a5, a6); }
};

template<typename R, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
struct stdcall_function_ptr<R(T0, T1, T2, T3, T4, T5, T6, T7)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2, T3, T4, T5, T6, T7);
    R operator() (T0 a0, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7) { return (*(fn_t)ptr)(a0, a1, a2, a3, a4, a5, a6, a7); }
};

template<typename R, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
struct stdcall_function_ptr<R(T0, T1, T2, T3, T4, T5, T6, T7, T8)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2, T3, T4, T5, T6, T7, T8);
    R operator() (T0 a0, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8) { return (*(fn_t)ptr)(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
};

template<typename R, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
struct stdcall_function_ptr<R(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9);
    R operator() (T0 a0, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8, T9 a9) { return (*(fn_t)ptr)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
};

template<typename R, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
struct stdcall_function_ptr<R(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
    R operator() (T0 a0, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8, T9 a9, T10 a10) { return (*(fn_t)ptr)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
};

template<typename R, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
struct stdcall_function_ptr<R(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
    R operator() (T0 a0, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8, T9 a9, T10 a10, T11 a11) { return (*(fn_t)ptr)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
};

template<typename R, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
struct stdcall_function_ptr<R(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
    R operator() (T0 a0, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8, T9 a9, T10 a10, T11 a11, T12 a12) { return (*(fn_t)ptr)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
};

template<typename R, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13>
struct stdcall_function_ptr<R(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);
    R operator() (T0 a0, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8, T9 a9, T10 a10, T11 a11, T12 a12, T13 a13) { return (*(fn_t)ptr)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
};

template<typename R, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12, typename T13, typename T14>
struct stdcall_function_ptr<R(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)> : stdcall_function_address
{
    typedef R(__stdcall *fn_t)(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);
    R operator() (T0 a0, T1 a1, T2 a2, T3 a3, T4 a4, T5 a5, T6 a6, T7 a7, T8 a8, T9 a9, T10 a10, T11 a11, T12 a12, T13 a13, T14 a14) { return (*(fn_t)ptr)(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
};

} // namespace detail

template<typename Signature>
struct api_function : detail::stdcall_function_ptr<Signature>
{
    api_function(HMODULE hModule, const char* functionName) 
    {
        ptr = (ptr_t)GetProcAddress(hModule, functionName);
    }
    api_function(const char* moduleName, const char* functionName)
    {
        ptr = (ptr_t)GetProcAddress(LoadLibraryA(moduleName), functionName);
    }
};

#endif // API_FUNCTION_H_INCLUDED_

PM MAIL ICQ   Вверх
mes
Дата 29.3.2010, 22:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(GoldFinch @  29.3.2010,  20:44 Найти цитируемый пост)
а свои классы выглядят страшно %)

Цитата(GoldFinch @  29.3.2010,  20:44 Найти цитируемый пост)
  R operator() (T0 a0, T1 a1, T2 a2) { return (*(fn_t)ptr)(a0, a1, a2); }

угу, а что разве такое не работает ? :
Код

typedef void (*FN)();

template <class T>
struct fn_wrapper {
    fn_wrapper (FN fn): m_fn( (T)fn) {}
    
    operator T () { return m_fn; }
    
    T m_fn;
};


   fn_wrapper<void (__stdcall *)(int)> f1 = ... ;

сорри за грязный код..сейчас времени больше  нет smile


Это сообщение отредактировал(а) mes - 29.3.2010, 22:59


--------------------
PM MAIL WWW   Вверх
GoldFinch
Дата 29.3.2010, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



хм... про operator T я не подумал
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0956 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.