Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
59 / 59 / 52
Регистрация: 19.11.2010
Сообщений: 218
1

Универсальный wrapper для вызова функций по указателю

06.09.2018, 20:24. Просмотров 1057. Ответов 8
Метки нет (Все метки)


Всем привет!
Я хочу написать объект, в методе которого смогу вызывать любые API функции. В метод я хочу передавать указатель на нужную мне API функцию и ещё как-то нужно передать параметры. Тут возникает у меня вопрос: как это можно сделать? Ведь параметры от функции к функции различаются как по количеству, так и по типу. Не могу сообразить, как вывернуться. Есть идея: передавать параметры врапперу в массиве, а затем в нём выделять RWX память и в рантайме генерировать опкоды асма:
Assembler
1
2
3
4
5
push param[0]
push param[1]
...
push param[N]
call x
Но хочется решить проблему синтаксичеки.
Псевдокод пока такой:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DWORD CallManager::wrapper(LPVOID func, params)
{
    DWORD result = func(params);
    return result;
}
 
void main()
{
    LPVOID f1 = MessageBoxA; //MessageBoxA(NULL, "Title","caption",0);
    LPVOID f2 = ExitProcess; //ExitProcess(0);
    
    CallManager cm = new CallManager();
    cm->wrapper(f1,NULL, "Title","caption",0);
    cm->wrapper(f2,0);
}
Буду рад любой подсказки!
Заранее спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.09.2018, 20:24
Ответы с готовыми решениями:

Функция для вызова других функций
короч нужна функция, которая принимала какое либо значения к примеру интовое, и в зависимости от...

Слишком мало аргументов для вызова функций
Никак не пойму почему вызывается эта ошибка. #include <stdlib.h> #include <stdio.h> #include...

Зачем нужно преобразование при присваивании указателю результата вызова malloc?
Здравия всем! Когда я читал уроки по выделению памяти, там, в большинстве случаев, был примерно...

Вызов функций по указателю
Введение Как известно, прямой работы с указателями в VB нет. Однако есть функции для почти...

8
шКодер самоучка
2127 / 1843 / 902
Регистрация: 09.10.2013
Сообщений: 4,029
Записей в блоге: 7
06.09.2018, 20:38 2
Artorios, а какой смысл в данной прослойке?
0
59 / 59 / 52
Регистрация: 19.11.2010
Сообщений: 218
06.09.2018, 21:44  [ТС] 3
Я пишу свой класс для перехвата апих [знаю, что уже есть готовые варианты :-)]. Это нужно мне для того, чтобы класс был универсальным для любых API.
0
Don't worry, be happy
16970 / 9851 / 1897
Регистрация: 27.09.2012
Сообщений: 24,429
Записей в блоге: 1
09.09.2018, 20:27 4
std::function не подходит?
1
Evg
Эксперт CАвтор FAQ
21153 / 8169 / 628
Регистрация: 30.03.2009
Сообщений: 22,468
Записей в блоге: 30
09.09.2018, 20:42 5
А просто ... чем не устраивает? Правда придётся сравнивать указатель на функцию с адресами всех системных функций, чтобы получить информацию о количестве параметров. Сильно дело упростил бы дополнительный параметр, говорящий о том, сколько параметров передаётся, но, вероятно, сие не устроит

Но по другому без препроцессора скорее всего не получится, а препроцессор тут не поможет, т.к. у тебя метод, а не глобальный интерфейс. Если он находится внутри шаблона, то синтаксический сахар новых версий Си++ может и позволит сделать

По другому скорее всего никак
1
Don't worry, be happy
16970 / 9851 / 1897
Регистрация: 27.09.2012
Сообщений: 24,429
Записей в блоге: 1
09.09.2018, 21:51 6
Лучший ответ Сообщение было отмечено Artorios как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<typename Func, typename ... Args>
auto CallManager::wrapper(Func func, Args && ... args)//Это будет что-то типа std::invoke...?
{
    return func(std::forward<Args>(args)...);
}
 
int main()
{
    std::function<decltype(MessageBoxA)> f1 = MessageBoxA; //MessageBoxA(NULL, "Title","caption",0);
    std::function<decltype(ExitProcess)> f2 = ExitProcess; //ExitProcess(0);
    
    CallManager cm = new CallManager();
    cm->wrapper(f1,NULL, "Title","caption",0);
    cm->wrapper(f2,0);
}
1
Evg
Эксперт CАвтор FAQ
21153 / 8169 / 628
Регистрация: 30.03.2009
Сообщений: 22,468
Записей в блоге: 30
10.09.2018, 12:51 7
Croessmah, да, примерно такое я и имел в виду. Но тут всё-таки используются промежуточные объекты f1 и f2. А без них нельзя? Ну т.е. засунуть указатель на функцию тоже как-нибудь на место шаблонного параметра
0
Don't worry, be happy
16970 / 9851 / 1897
Регистрация: 27.09.2012
Сообщений: 24,429
Записей в блоге: 1
10.09.2018, 13:05 8
Evg, можно и без него, прямо так:
C++
1
cm->wrapper(MessageBoxA, NULL, "Title","caption",0);
только я не знаю для чего и как впоследствии это будет использоваться.
Вполне вероятно, что шаблон вовсе не подойдет.
Тогда придется шаблонную кухню прятать внутрь, как в std::any.
0
59 / 59 / 52
Регистрация: 19.11.2010
Сообщений: 218
10.09.2018, 14:39  [ТС] 9
Спасибо! Работает!
Только вот я ещё захотел получить адрес функции внутри метода. Нагуглил, что это делается через target.
Но у меня результат всегда даёт NULL (
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template<typename Func, typename ... Args>
auto wrapper(Func func, Args && ... args)
{   
    auto* address = func.template target<Func>();
    printf("address: 0x%08x\n", address);
    return func(std::forward<Args>(args)...);
}
 
void main()
{
    function<decltype(MessageBoxA)> f1 = MessageBoxA;
    fp = *f.target<decltype(MessageBoxA)>();
    wrapper(f1, (HWND)NULL, "Title", "caption", 0);
 
}
Почему же так?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.09.2018, 14:39

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Вызов любых функций по указателю
Пока не работал форум, ковырялся в рантайме VB :). Иследуя функции VBA6 придумал способ вызова...

Универсальный способ проверки группы функций
Добрый день, есть группа методов которые могут возвращать -1. Пример $p-&gt;moveTo('1');...

Передать сумму по ссылке и по указателю (перегрузка функций)
Посмотрите пожалуйста правильно ли написала у меня есть значение a и b,мне надо передать сумму по...

Особенности вызова функций
Какие особенности вызова функций, в описании которых использованы ключевые слова _stdcall, _cdecl,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.