Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 24, средняя оценка - 4.96
demogor
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 10
#1

Использование строк в макросах С++ - C++

11.02.2013, 13:19. Просмотров 3253. Ответов 23
Метки нет (Все метки)

Доброго времени суток всем!
Возникла небольшая проблема - не могу понять, возможно ли сделать нечто подобное, и, если возможно, то как.
Есть макрос, объявляющий функцию:

C++
1
2
3
4
#define DECLARE_FUNC(name1, body, type_cl, ...)\
    __declspec(dllexport) void type_cl name1##_func(__VA_ARGS__){\
    body;\
}\
Используется следующим образом:
C++
1
DECLARE_FUNC(testDeclare, "debug_msg(\"TestDeclare\",\"hello!\")", void, void);
где строка - вызов функции debug_msg(запись в файл форматированной строки).

Собственно, вопрос - как это сделать правильно? В текущем варианте нет никакой реакции на вызов функции testDeclare_func().

P.S. В следующем варианте
C++
1
2
3
4
5
#define DECLARE_FUNC(name1, body, type_cl, ...)\
    __declspec(dllexport) void type_cl name1##_func(__VA_ARGS__){\
    debug_msg("TestDeclare","hello!");\
    body;\
}\
вывод из debug_msg("TestDeclare","hello!"); вполне адекватно отрабатывает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.02.2013, 13:19
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Использование строк в макросах С++ (C++):

Использование строк.Использование структур - C++
Задачка: Дана строка,состоящая из групп нулей и едениц. Найти и вывести на экран группы с нечетным количеством символов. И еще одна: ...

Использование строк - C++
Помогите с алгоритмом программы: вводим текст происходит проверка на наличие цифр прописью, заменяет их и выводит исправленый...

Использование файлов и строк - C++
Уважаемые программисты! Нужна ваша помощь, заканчиваю написание диплома и возникла следующая проблемка: Есть программа, которая все...

Использование строк и файлов - C++
С помощью текстового редактора создать файл, содержащий текст, длина которого не превышает 1000 символов (длина строки текста не должна...

Использование собственного класса строк - C++
Здравствуйте, уважаемые господа. Есть реализация собственного класса строк: class MyString { private: size_t length; ...

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

23
vxg
Модератор
3169 / 1972 / 221
Регистрация: 13.01.2012
Сообщений: 7,579
12.02.2013, 10:46 #16
Цитата Сообщение от Evg Посмотреть сообщение
после препроцессора превратится в
я думал что препроцессор споткнется об запятую перед hello, но пример работает. как это возможно?
1
Evg
Эксперт CАвтор FAQ
17954 / 6185 / 414
Регистрация: 30.03.2009
Сообщений: 16,974
Записей в блоге: 27
12.02.2013, 22:05 #17
Цитата Сообщение от nonedark2008 Посмотреть сообщение
Evg, как я понял, у него есть библиотееа на C++. Но ее нужно очень часто менять, но ему очень не хочется постоянно ее перекомпилировать для этого. Поэтому он хочет, чтобы внутри его библиотеки использовались функции из скриптового языка. Т. е. можно поменять что-то в библиотеке просто изменив функции в скрипте.
Ну... при такой постановке вопроса в компилируемых языках настолько просто это не решается.

Цитата Сообщение от vxg Посмотреть сообщение
я думал что препроцессор споткнется об запятую перед hello, но пример работает. как это возможно?
Слушай, хороший вопрос. Мне казалось чем-то самим собой разумеющимся то, что наличие скобок экранирует запятые. Причём наверняка оно так и есть, но я как-то никогда об этом не задумывался, просто использовал и всё. Надо бы почитать
0
demogor
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 10
12.02.2013, 22:29  [ТС] #18
Evg, если о lua_State(
А что за константа в 4-м параметре?
), то это состояние текущего экземпляра луа интерпретатора. Честно говоря, сам не до конца понимаю смысла его, потому представляю как некий контейнер, содержащий аргументы lua функции(стек, по факту).
Вариант подачи тела, предоставленный выше, логичен, но хотелось именно строку передавать, что бы была возможность вытягивать тело функции из отдельного файла(nonedark абсолютно прав).
Необходимость этого в том, что я разбираю потихоньку клиент и для получения информации о функциях их необходимо перехватывать. Каждый раз, что бы это сделать, необходимо описывать функции - а это не слишком удобно. Именно для этого и нужны макросы, потому и хочу максимально автоматизировать процесс.
Более того, в принципе, для начала меня вполне устроит макрос, который будет объявлять и описывать функцию с выводом аргументов в файл при перехвате.
0
Evg
Эксперт CАвтор FAQ
17954 / 6185 / 414
Регистрация: 30.03.2009
Сообщений: 16,974
Записей в блоге: 27
12.02.2013, 22:39 #19
Цитата Сообщение от demogor Посмотреть сообщение
Вариант подачи тела, предоставленный выше, логичен, но хотелось именно строку передавать, что бы была возможность вытягивать тело функции из отдельного файла(nonedark абсолютно прав)
Для компилируемого языка сие попросту нормально не реализуемо. Единственный способ - это из программы сгенерить файл на Си, далее из программы же вызвать компилятор и сформировать динамическую библиотеку, далее из программы же эту библиотеку подключить (в unix-системах есть интерфейс dlopen и ко, наверняка в винде есть то же самое). Либо использовать всякие нанотехнологии типа OpenCL, которые по большому счёту точно так же являются вызовом компилятора, только всё это монолитно встраивается в программу.

Генерация исходника на ходу, как уже говорилось, характерна для всяких скриптовых языков, но не для компилируемых. Потому как при работе скриптового языка всегда есть интерпретатор, который всё может, а компилируемые языки характеризуются тем, что при исполнении программы компилятор уже не нужен

Добавлено через 1 минуту
А в целом я твою задачу всё равно не понимаю из-за невнятной постановки

Ну или могу порекомендовать на ходу генерировать функции на Lua, а не на Си. Интерпретатор Lua встраивается в программу, а потому сие вполне допустимо
0
demogor
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 10
12.02.2013, 22:49  [ТС] #20
Я хочу добавлять хуки сразу из луа, но для этого нужно как-то описывать тело функции(а не только ее декларировать). Вариант с подачей из текстового файла сначала показался самым подходящим но, как я уже понял, это не представляется возможным.
Впрочем, думаю, мне вполне хватит варианта с выводом аргументов.
0
Evg
Эксперт CАвтор FAQ
17954 / 6185 / 414
Регистрация: 30.03.2009
Сообщений: 16,974
Записей в блоге: 27
13.02.2013, 17:35 #21
Напомню ещё раз. Правильно поставленный вопрос - это половина ответа. Если ты хочешь, чтобы тебе ответили - потрать 10 минут и нормально опиши проблему. Мне, если честно, уже становится впадлу читать по три раза твои посты, чтобы догадаться, что же ты имеешь ввиду
0
demogor
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 10
14.02.2013, 22:00  [ТС] #22
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#define RF_IMP(ret, type_cl, name1, format, adres, ...)\
    typedef ret (type_cl * t##name1 ) (va_list args);\
    t##name1 name1##_Detour = ( t##name1 ) ( adres );\
    void type_cl name1##_hook(char *txt, ...);\
    BYTE name1##_var[6];\
    void type_cl name1##_hook (char *txt, ...) {\
    txt=format;\
    va_list arg;\
    va_start(arg, txt);\
    name1##_Detour(arg);\
    debug_msg("ParseArgs",txt, arg);\
    va_end(arg);\
}\
Написал вышеприведенный код.
Вроде бы все хорошо, без возврата в оригинальную функцию выводит полученные аргументы, бла-бла-бла, всемирное добро и счастье.
Но вот как перейти к оригинальной функции - вот тут-то и затык. Возникает ошибка http://*************/s/2PHjK, предположительно связанная с тем, что переменное число аргументов не может работать с calling conventions, очищающими стек(__stdcall, к примеру). Впрочем, и с __cdecl'ом та же проблема возникла.
На самом деле, va_list здесь не нужен, достаточно бы передать аргументы из макроса(__VA_ARGS__) - но тут возникает проблема: вызов функции не получается провести с __VA_ARGS__(насколько понимаю, внутри содержится список аргументов с типами, в результате чего компилятор ругается на то, что нельзя вызвать функцию name_Detour(int a1).

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

Пример использования:
C++
1
2
3
RF_IMP(int, WINAPI, send2, "%d, %d, 0x%X, %d, %d, %d, %d", 0x17E4D18, SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, 
       LPWSAOVERLAPPED lpOverlapped, 
       LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
Благодарю за внимание!
0
Evg
Эксперт CАвтор FAQ
17954 / 6185 / 414
Регистрация: 30.03.2009
Сообщений: 16,974
Записей в блоге: 27
15.02.2013, 18:25 #23
Сначала был пример:

Цитата Сообщение от Evg Посмотреть сообщение
Код

C++
1
2
3
4
5
6
#define DECLARE_FUNC(name1, body, type_cl, ...) \
  __declspec(dllexport) type_cl name1##_func(__VA_ARGS__) {\
    body; \
  }
 
DECLARE_FUNC (testDeclare, debug_msg ("TestDeclare", "hello!"), void, int x, int y)
после препроцессора превратится в

C++
1
__declspec(dllexport) void testDeclare_func(int x, int y) { debug_msg ("TestDeclare", "hello!"); }
Затем был вопрос:

Цитата Сообщение от vxg Посмотреть сообщение
я думал что препроцессор споткнется об запятую перед hello, но пример работает. как это возможно?
Вот что на это говорит стандарт:

ISO/IEC 9899:1999 (E)
...
6.10.3 Macro replacement
...
11. The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments or the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens, but comma preprocessing tokens between matching inner parentheses do not separate arguments. If there are sequences of preprocessing tokens within the list of arguments that would otherwise act as preprocessing directives, the behavior is undefined.
Вот как надо поступать, если мы хотим вставить круглые скобки в качестве параметра макроса:

C
#define LB (
#define RB )
#define A(x1, x2, x3) x1 qqq x2 qqq x3
A (LB , x , RB)
после препроцессора превратится

C
( qqq x qqq )
0
demogor
0 / 0 / 0
Регистрация: 11.02.2013
Сообщений: 10
15.02.2013, 19:46  [ТС] #24
Любопытно. Спасибо за информацию.
А что насчет передачи аргументов в функцию(Использование строк в макросах С++
И есть ли какой-либо способ перехвата функциидля различных соглашений о вызовах(__stdcall, к примеру) без указания аргументов функции(к примеру, объявление общего прототипа с va_list в качестве аргумента)?

Тобишь, к примеру, есть 3 функции:
C++
1
2
3
int WINAPI WSASend(Socket s, blablabla...);
void __stdcall WhatDidThisFunctionDoAnyImagine(int a1, char *a2, bool a3); 
void * __cdecl BlaBlaReallyBla(void *arg);
и общий прототип для перехвата в стиле
C++
1
2
3
4
5
6
void name##_hook(char *format, va_list va)
{
   va_start(va,format);
   name##_original(va);
   va_end(va);
}
?
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.02.2013, 19:46
Привет! Вот еще темы с ответами:

Использование одномерного массива строк - C++
Здравствуйте! Задание: Имеется файл 1.txt в котором содержатся строки неизвестной длины. Так же имеется файл 2.txt в котором так же...

Метки в макросах в ассемблерной вставке - C++
В C++ написан макрос с ассемблерной вставкой, который содержит в себе метку "doit" и команду перехода на неё: #define MYMACRO(x, y, z)...

Использование указателей на функцию для обработки строк - C++
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; void check(char *a, char *b, int...

Использование строк, как одномерные массивы символов - C++
Вот такая задачка Дана строка символов, состоящая из цифр, разделенных пробелами. Вывести четные числа этой строки Это оконный режим...


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

Или воспользуйтесь поиском по форуму:
24
Yandex
Объявления
15.02.2013, 19:46
Ответ Создать тему
Опции темы

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