![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
YouROK |
|
|||
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 21.7.2011 Репутация: нет Всего: нет |
Есть строка допустим "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++? Это сообщение отредактировал(а) YouROK - 29.12.2011, 15:27 |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
нифига не понял
![]() |
|||
|
||||
YouROK |
|
|||
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 21.7.2011 Репутация: нет Всего: нет |
в программу ко мне по сети приходит строка
"printf(\"%s %d\"); chars:\"Hello world\", int:25;" моя программа должна вызвать функцию с этими аргументам функция одна, а вот аргументы все время разные и количество их тоже меняется. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
распарсив эту часть, ты получаешь массив указателей на токены, и узнаешь кол-во аргументов. далее, итерируйся по списку полученных указателей и выводи при помощи std::cout |
|||
|
||||
YouROK |
|
|||
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 21.7.2011 Репутация: нет Всего: нет |
||||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
так передай в функцию список указателей. в чем сложность?
|
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
YouROK, такое действительно можно делать или на ассемблере, или перебирать в коде все возможные варианты (т.е. сделать код для всех возможных комбинаций параметров).
Мой тебе совет, пересмотри вообще постановку задачи, так как подобное решение не только трудно реализуемо, но и сильно снижает надежность кода. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
варианты чего? он получает строки. варианты строк? ![]() т.е. перегрузить функцию для всех возможных типов и количеств аргументов?. повторяю: он получает только строки. |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
варианты наборов аргументов функций.
|
|||
|
||||
YouROK |
|
|||
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 21.7.2011 Репутация: нет Всего: нет |
Видимо придется делать 6 функций с разным количеством параметров, думаю больше 5 аргументов не будет.
|
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
зачем?
|
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
||||
|
||||
feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 11 Всего: 45 |
Теоретически, можно постараться реализовать всё это через va_list. Однако в таком случае передача неверных аргументов может завершить Вашу программу сигфолтом. Как минимум, Вам придётся проверять соответствие форматов в строке printf и передаваемых ей аргументов. То есть разбирать форматную строку.
Я всё же предлагаю реализовать задачу иначе. Простите, запишу всё через struct, легко можно будет перепесать и через классы.
Это сообщение отредактировал(а) feodorv - 6.1.2012, 23:53 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Вариант с va_list имеет еще один недостаток - этот самый va_list очень компиляторно и системное зависим. Недавно столкнулся - на 64х битном х86 этот самый лист не void*, как у всех, а массив (из 1 элемента) весьма развесистой структуры
|
|||
|
||||
586 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2243 Регистрация: 8.5.2006 Репутация: 10 Всего: 146 |
|
|||
|
||||
YouROK |
|
|||
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 21.7.2011 Репутация: нет Всего: нет |
feodorv,
В том то и дело что функции которые принимают аргументы не мои и их изменить нельзя, в конце концов сделал парсинг из строки в вектор типа boost::any и сделал 7 вызовов функций, в зависимости от количества аргументов вызывается та или иная функция. правда получилось немного коряво, но все работает. Думаю вопрос интересный, может кто еще предложит идеи. Интересует как это можно сделать на ассемблере, есть кто разбирается, может выложит хоть что нибудь? Пусть и архетектурнозависимо Добавлено через 4 минуты и 5 секунд Суть в том что количество аргументов("abc",-2 у тебя их два) у меня все время разное |
|||
|
||||
586 |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2243 Регистрация: 8.5.2006 Репутация: 10 Всего: 146 |
||||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
||||
|
||||
500mhz |
|
|||
![]() шайтан ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1017 Регистрация: 5.5.2008 Где: Киев / Italy Репутация: нет Всего: 14 |
ну можно внутри функции сравнить значение стека, и понять сколько аргументов там лежит
пример
Это сообщение отредактировал(а) 500mhz - 13.1.2012, 21:00 -------------------- |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
500mhz, откуда ты взял "предыдущий адрес стека"?
|
|||
|
||||
500mhz |
|
|||
![]() шайтан ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1017 Регистрация: 5.5.2008 Где: Киев / Italy Репутация: нет Всего: 14 |
ну допустим пусть он передаеться в ЕАХ при вызове функции
-------------------- |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
500mhz, интересно, а какой это тип вызова функции такой? что-то я не помню.
А потом, количество и тип аргументов известен на этапе выполнения. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 49 Всего: 110 |
нет же. стек формируется компилятором. |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
У ТС задача обратная - у него известны параметры (run-time), надо самому сформировать стек для вызова Если никакие параметры не передаются в регистрах (все в стеке), и они все (вне зависимости от типа) одинаковой длинны (с учетом выравнивания при помещении в стек), то такой вызов можно сформировать. Нужно просто явно вычислить все параметры (с первого или с последнего, в зависимости от типа вызова), и запихнуть их в стек (командой push). Потом позвать функцию, как void (*)(void). Если тип функции был cdecl, то после возврата надо сбросить стек (через add sp,<size>) |
|||
|
||||
500mhz |
|
|||
![]() шайтан ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1017 Регистрация: 5.5.2008 Где: Киев / Italy Репутация: нет Всего: 14 |
ха, с gcc не прокатывает он компилит нечто типа
может есть какие то ключи для компиляции с push ? -------------------- |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
||||
|
||||
500mhz |
|
|||
![]() шайтан ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1017 Регистрация: 5.5.2008 Где: Киев / Italy Репутация: нет Всего: 14 |
xvr
правильно аргументы на стеке, но сам стек нифига не меняеться -------------------- |
|||
|
||||
xvr |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
gcc заранее резервирует необходимое место на стеке (в прологе функции). Но ничего не мешает это место дополнительно алоцировать в процессе вызова функции (теми самыми push'ами) Кстати, для __stdcall типа вызова gcc явно резервирует место в стеке (хотя и не с помощью push, но резервирует)
Помечен 2й вызов func, первая же комманда subl $12, %esp резервирует место в стеке (непосредственно в месте вызова) Добавлено @ 14:32 Хотя, присмтрелся внимательно - это не резервирование места, а восстановление места (стека), которое сбросит __stdcall функция. Но сути это не меняет - стек можно двигать в процессе работы функции, т.е. вариант с push должен работать Это сообщение отредактировал(а) xvr - 15.1.2012, 14:33 |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |