реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Добавление смещения к указателю на функцию., Переменная типа указатель на функцию.
_Алекс
сообщение Dec 25 2006, 15:49
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 252
Регистрация: 14-09-06
Пользователь №: 20 377



Объявил переменную – указатель на функцию, вызываю pf();, получилось. Стало необходимо добавить смещение к началу вызова функции, чтоб выполнялась с определенного места а не сначала, пытаюсь прибавить константу, пишет не совместимость типов. Не подскажите как правильно добавить смещение к указателю на функцию, в виде константы типа usigned int или char.
Go to the top of the page
 
+Quote Post
jorikdima
сообщение Dec 25 2006, 15:53
Сообщение #2


тут может быть ваша реклама
*****

Группа: Свой
Сообщений: 1 164
Регистрация: 15-03-06
Из: Санкт-Петербург/CA
Пользователь №: 15 280



То есть чтоб функция не с начала начала работать???
Такое невозможно помоему, да и не логично
Go to the top of the page
 
+Quote Post
_Алекс
сообщение Dec 25 2006, 16:14
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 252
Регистрация: 14-09-06
Пользователь №: 20 377



Цитата(jorikdima @ Dec 25 2006, 15:53) *
То есть чтоб функция не с начала начала работать???
Такое невозможно помоему, да и не логично


Такое возможно, но не знаю как преобразовать тип указатель на функцию и константу, чтоб их суммировать. Нужно вот для чего, например есть в функции задержка на 20мс, чтоб колом все не стояло 20мс, выходим из функции запоминаем адрес возврата, делаем что –то другое полезное и возвращаемся через примерно 20мс в точку выхода.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 25 2006, 16:26
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(_Алекс @ Dec 25 2006, 15:14) *
Нужно вот для чего, например есть в функции задержка на 20мс, чтоб колом все не стояло 20мс, выходим из функции запоминаем адрес возврата,

и указатель стека. Кроме того, "запоминаем" это нормально, а написанное Вами ранее "константу
прибавляем" - есть верный путь к проблемам.
Цитата
делаем что –то другое полезное и возвращаемся через примерно 20мс в точку выхода.

Все не просто а очень просто - сладкая парочка setjmp() longjmp() официальный путь решения подобных проблем.
Ну а вообще и о системе подумать можно - вариации на тему sleep().


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
dxp
сообщение Dec 25 2006, 16:27
Сообщение #5


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(_Алекс @ Dec 25 2006, 19:14) *
Цитата(jorikdima @ Dec 25 2006, 15:53) *

То есть чтоб функция не с начала начала работать???
Такое невозможно помоему, да и не логично

Такое возможно, но не знаю как преобразовать тип указатель на функцию и константу, чтоб их суммировать.

Функции в С всегда работают сначала. Нельзя средствами языка валидно вызвать функцию, чтоб попасть в ее середину.

Цитата(_Алекс @ Dec 25 2006, 19:14) *
Нужно вот для чего, например есть в функции задержка на 20мс, чтоб колом все не стояло 20мс, выходим из функции запоминаем адрес возврата, делаем что –то другое полезное и возвращаемся через примерно 20мс в точку выхода.

Это вам RTOS нужна. Под ней все это реализуется нативно. Или тогда руками соорудить автомат состояний и ходить по состояниям. Т.е. при входе в функцию анализируется переменная состояния и осуществляется переход за цикл (или куда там еще надо).


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Dec 25 2006, 16:58
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Механизм сопрограмм на макросах поможет и без RTOS
http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
vmp
сообщение Dec 25 2006, 17:05
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070



Если нельзя, но очень хочется...
Попробуйте привести указатель к типу unsigned int, выполнить арифметику и затем привести к исходному типу. Не обещаю, что получится.

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

Как показывает практика, подобными извращениями обычно страдают люди, переходящие с ассемблера на Си и стремящиеся сэкономить несколько микросекунд в редко используемой функции исключительно из любви к искусству. Со временем и опытом это проходит.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 25 2006, 17:32
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(sensor_ua @ Dec 25 2006, 15:58) *
Механизм сопрограмм на макросах поможет и без RTOS

Конечный автомат уже поминался (во что его оборачивать это дело уже второе), но решает он часть проблемы, ибо про 20ms он ведать не ведает и тем более прервать текущую задачу для более-менее точной выдержки не сможет. Если, конечно вырожденные случаи не рассматривать.

Цитата
Не обещаю, что получится.

Да формально изменить указатель получится - не имеет права не получиться. А вот результат сего действия будет покрыт мраком sad.gif.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
sensor_ua
сообщение Dec 25 2006, 17:53
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387



Цитата
Конечный автомат уже поминался

Согласен, но, ИМХО, странный вопрос товарища как-раз о том, КАК сделать, а не ЧТО. Механизм сопрограмм позволяет именно вернуться в точку предыдущего выхода. Вызов той же функции через сколько-то там мс позволит продолжить выполнение чего-то там по алгоритму.
Цитата
про 20ms он ведать не ведает и тем более прервать текущую задачу для более-менее точной выдержки не сможет

Разве кто-то говорил о точности выдержки времени (и на чём и при каких других условиях?) и о жёстком риалтайме? Тут, похоже, _Алекс сам не знает ещё чего хочетwink.gif или захочет...


--------------------
aka Vit
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 25 2006, 18:04
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(sensor_ua @ Dec 25 2006, 16:53) *
Тут, похоже, _Алекс сам не знает ещё чего хочетwink.gif или захочет...

Посему и поминание RTOS как средства максимально припособленного к "незнаю что" было вполне уместным smile.gif.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
_artem_
сообщение Dec 25 2006, 18:13
Сообщение #11


учащийся
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249



Цитата(_Алекс @ Dec 25 2006, 14:49) *
Объявил переменную – указатель на функцию, вызываю pf();, получилось. Стало необходимо добавить смещение к началу вызова функции, чтоб выполнялась с определенного места а не сначала, пытаюсь прибавить константу, пишет не совместимость типов. Не подскажите как правильно добавить смещение к указателю на функцию, в виде константы типа usigned int или char.


имхо в С все траснформации с пойнтером разрешаются через void* тип. продекларируйте такой пойнтер а затем присвойте ему указатель функции с кастингом на void и прибавьте смешение. затем вызом функции через результируюший пойнтер с кастингом как указатель функции. Правда размерность смешения надо урегулировать.


--------------------
Зачем лаять на караван , когда на него можно плюнуть?

Go to the top of the page
 
+Quote Post
Rst7
сообщение Dec 26 2006, 09:26
Сообщение #12


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата(_artem_ @ Dec 25 2006, 17:13) *
имхо в С все траснформации с пойнтером разрешаются через void* тип. продекларируйте такой пойнтер а затем присвойте ему указатель функции с кастингом на void и прибавьте смешение. затем вызом функции через результируюший пойнтер с кастингом как указатель функции. Правда размерность смешения надо урегулировать.


А с каких пор стали допустимы операции +, += и так далее с указателем типа void* ?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
dxp
сообщение Dec 26 2006, 15:58
Сообщение #13


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Rst7 @ Dec 26 2006, 12:26) *
Цитата(_artem_ @ Dec 25 2006, 17:13) *

имхо в С все траснформации с пойнтером разрешаются через void* тип. продекларируйте такой пойнтер а затем присвойте ему указатель функции с кастингом на void и прибавьте смешение. затем вызом функции через результируюший пойнтер с кастингом как указатель функции. Правда размерность смешения надо урегулировать.


А с каких пор стали допустимы операции +, += и так далее с указателем типа void* ?

Ну, надо написать класс TVoidPtr, в котором определить оные операции. И будет полная икэбана. smile.gif smile.gif smile.gif Правда, это уже не С. smile.gif


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
_artem_
сообщение Dec 26 2006, 16:29
Сообщение #14


учащийся
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 29-10-05
Из: города контрастов
Пользователь №: 10 249



Цитата(Rst7 @ Dec 26 2006, 08:26) *
Цитата(_artem_ @ Dec 25 2006, 17:13) *

имхо в С все траснформации с пойнтером разрешаются через void* тип. продекларируйте такой пойнтер а затем присвойте ему указатель функции с кастингом на void и прибавьте смешение. затем вызом функции через результируюший пойнтер с кастингом как указатель функции. Правда размерность смешения надо урегулировать.


А с каких пор стали допустимы операции +, += и так далее с указателем типа void* ?


Вы правы - в написанном ошибка. Чтоб замалить прошение) написал пример который КОМПИЛИРУЕТСЯ без ошибок на bcc32 :

Код
void test(void)
{
    int i = 0;
    i++;
}


void main (void)
{

    void (*fp)(void);

    fp = (void(*)(void))((unsigned long int)(&test) + 100);

    fp();
}


Наверно надо обратить внимание на правильную размерность указателя на функцию когда делается кастинг перед сложением .


--------------------
Зачем лаять на караван , когда на него можно плюнуть?

Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 26 2006, 18:16
Сообщение #15


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(_artem_ @ Dec 26 2006, 15:29) *
Наверно надо обратить внимание на правильную размерность указателя на функцию когда делается кастинг перед сложением .
Можно подключить stdint.h, там объявлен тип uintptr_t - беззнаковое целое в которое точно уместится указатель, и использовать этот тип. Но только для чего-нибудь полезного, а не для решения исходной задачи :-)


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 20:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.01504 секунд с 7
ELECTRONIX ©2004-2016