Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Как передать функции несколько параметров |
Автор: YouROK 29.12.2011, 15:26 |
Есть строка допустим "printf(\"%s %d\"); chars:\"Hello world\", int:25;" Моя функция парсит строку получаем строку char *paramstr = "%s %d" и список или что то в этом роде пока еще не определился 1)char* "Hello world" 2)int 25 далее идет вызов printf(paramstr,тут как-то надо вставить эти параметры); думал как-нибудь собрать va_list но там работа со стеком, что без ассемблера не сделаешь???? подскажите кто-нибудь, может через boost можно как-то или стандартными способами c++? |
Автор: boostcoder 29.12.2011, 15:29 |
нифига не понял ![]() |
Автор: YouROK 29.12.2011, 15:35 |
в программу ко мне по сети приходит строка "printf(\"%s %d\"); chars:\"Hello world\", int:25;" моя программа должна вызвать функцию с этими аргументам функция одна, а вот аргументы все время разные и количество их тоже меняется. |
Автор: boostcoder 29.12.2011, 15:50 |
распарсив эту часть, ты получаешь массив указателей на токены, и узнаешь кол-во аргументов. далее, итерируйся по списку полученных указателей и выводи при помощи std::cout |
Автор: YouROK 29.12.2011, 16:03 |
printf был взят для примера мне нужно именно передать все полученные параметры в функцию допустим в function1(char*str,...); или function1v(char *str, va_list *list); |
Автор: boostcoder 29.12.2011, 16:32 |
так передай в функцию список указателей. в чем сложность? |
Автор: bsa 29.12.2011, 16:36 |
YouROK, такое действительно можно делать или на ассемблере, или перебирать в коде все возможные варианты (т.е. сделать код для всех возможных комбинаций параметров). Мой тебе совет, пересмотри вообще постановку задачи, так как подобное решение не только трудно реализуемо, но и сильно снижает надежность кода. |
Автор: boostcoder 29.12.2011, 16:49 |
варианты чего? он получает строки. варианты строк? ![]() т.е. перегрузить функцию для всех возможных типов и количеств аргументов?. повторяю: он получает только строки. |
Автор: bsa 29.12.2011, 17:06 |
варианты наборов аргументов функций. |
Автор: YouROK 29.12.2011, 17:48 |
Видимо придется делать 6 функций с разным количеством параметров, думаю больше 5 аргументов не будет. |
Автор: boostcoder 29.12.2011, 19:01 |
зачем? |
Автор: xvr 3.1.2012, 13:53 |
В gcc есть встроенные функции, которые (судя по названию) умеют делать нечто подобное. См http://info2html.sourceforge.net/cgi-bin/info2html-demo/info2html?%28gcc.info.gz%29Constructing%2520Calls |
Автор: feodorv 6.1.2012, 21:10 | ||||
Теоретически, можно постараться реализовать всё это через va_list. Однако в таком случае передача неверных аргументов может завершить Вашу программу сигфолтом. Как минимум, Вам придётся проверять соответствие форматов в строке printf и передаваемых ей аргументов. То есть разбирать форматную строку. Я всё же предлагаю реализовать задачу иначе. Простите, запишу всё через struct, легко можно будет перепесать и через классы.
|
Автор: xvr 6.1.2012, 23:09 |
Вариант с va_list имеет еще один недостаток - этот самый va_list очень компиляторно и системное зависим. Недавно столкнулся - на 64х битном х86 этот самый лист не void*, как у всех, а массив (из 1 элемента) весьма развесистой структуры |
Автор: 586 7.1.2012, 07:45 | ||
|
Автор: 586 13.1.2012, 18:26 | ||
В функцию my_printf можно сколько угодно аргументов передать. |
Автор: xvr 13.1.2012, 18:33 | ||
Какие могут быть типы параметров, какая платформа, какой компилятор, как описаны функции, которые надо вызывать? |
Автор: 500mhz 13.1.2012, 20:52 | ||
ну можно внутри функции сравнить значение стека, и понять сколько аргументов там лежит пример
|
Автор: bsa 13.1.2012, 21:32 |
500mhz, откуда ты взял "предыдущий адрес стека"? |
Автор: 500mhz 13.1.2012, 21:45 |
ну допустим пусть он передаеться в ЕАХ при вызове функции |
Автор: bsa 13.1.2012, 23:46 |
500mhz, интересно, а какой это тип вызова функции такой? что-то я не помню. А потом, количество и тип аргументов известен на этапе выполнения. |
Автор: boostcoder 13.1.2012, 23:54 |
нет же. стек формируется компилятором. |
Автор: xvr 14.1.2012, 14:09 |
У ТС задача обратная - у него известны параметры (run-time), надо самому сформировать стек для вызова Если никакие параметры не передаются в регистрах (все в стеке), и они все (вне зависимости от типа) одинаковой длинны (с учетом выравнивания при помещении в стек), то такой вызов можно сформировать. Нужно просто явно вычислить все параметры (с первого или с последнего, в зависимости от типа вызова), и запихнуть их в стек (командой push). Потом позвать функцию, как void (*)(void). Если тип функции был cdecl, то после возврата надо сбросить стек (через add sp,<size>) |
Автор: 500mhz 14.1.2012, 15:28 | ||
ха, с gcc не прокатывает он компилит нечто типа
может есть какие то ключи для компиляции с push ? |
Автор: xvr 14.1.2012, 18:42 |
Это неважно - вызываемая функция ожидает найти параметры в стеке, и она их там найдет. То, что они туда попадут не так, как это делает gcc роли не играет, главное что бы ничего не сломалось |
Автор: 500mhz 14.1.2012, 19:35 |
xvr правильно аргументы на стеке, но сам стек нифига не меняеться |
Автор: xvr 15.1.2012, 14:24 | ||||
gcc заранее резервирует необходимое место на стеке (в прологе функции). Но ничего не мешает это место дополнительно алоцировать в процессе вызова функции (теми самыми push'ами) Кстати, для __stdcall типа вызова gcc явно резервирует место в стеке (хотя и не с помощью push, но резервирует)
Помечен 2й вызов func, первая же комманда subl $12, %esp резервирует место в стеке (непосредственно в месте вызова) Добавлено @ 14:32 Хотя, присмтрелся внимательно - это не резервирование места, а восстановление места (стека), которое сбросит __stdcall функция. Но сути это не меняет - стек можно двигать в процессе работы функции, т.е. вариант с push должен работать |