Вызов функции с определенным контекстом - C (СИ)
Формулировка задачи:
Я ищу способ сообщить функции контекст вызова любым возможным способом, используя исключительно ANSI C. Я поясню что имею ввиду:
Представим что, у нас имеется некоторая структура, которая помимо всего прочего хранит указатели на функции, мы можем менять эти значения динамически, но к сожалению не имеем возможности внутри функции получить доступ к полям структуры.
Один из вариантов, который бы так же подошел это реализовать лямбда функции или функции с дефолтными значениями. Я знаю, что их нет в Си. Я ищу способ с эмитировать такое поведение.
Еще один из вариантов попытаться создать врапер для
некоторого класса
функций. Вероятно можно многого добиться используя макросы, но чет то я уже устал играть с ними в этот пазл поэтому прошу вашего совета. Понимаю вопрос обширный, но меня заинтересуют любые ваши идеи по существу.Решение задачи: «Вызов функции с определенным контекстом»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
/* imitation of class TAbstractContainer -- START */
typedef struct
{
int (*Push)(int data);
int element;
} TAbstractContainer;
int PushToAbstractContainer(int data)
{
/* some specific code here */
printf("In PushToAbstractContainer, data = %d\n", data);
return 0;
}
TAbstractContainer* CreateAbstractContainer(void)
{
TAbstractContainer *temp = malloc(sizeof(*temp));
temp->Push = PushToAbstractContainer;
return temp;
}
/* imitation of class TAbstractContainer -- END */
/* imitation of class TSpecializedContainer -- START */
typedef struct
{
int (*Push)(int data);
int element;
struct TSpecializedContainer* next;
} TSpecializedContainer;
int PushToSpecializedContainer(int data)
{
/* some code here */
printf("In PushToSpecializedContainer, data = %d\n", data);
return 3;
}
TSpecializedContainer* CreateSpecializedContainer(void)
{
TSpecializedContainer* temp = malloc(sizeof(*temp));
temp->element = 2;
temp->Push = PushToSpecializedContainer;
temp->next = NULL;
return temp;
}
/* imitation of class TSpecializedContainer -- START */
int main(void)
{
TAbstractContainer* ac = CreateAbstractContainer();
TSpecializedContainer* sc = CreateSpecializedContainer();
ac->Push(13);
sc->Push(444);
return 0;
}
Объяснение кода листинга программы
- Код начинается с заголовка файла и импортирования необходимых библиотек.
- Определяется структура
TAbstractContainerс указанием методаPushи переменнойelement. - Определяется функция
PushToAbstractContainer, которая имитирует методPushдляTAbstractContainer. - Определяется функция
CreateAbstractContainer, которая создает экземплярTAbstractContainerи возвращает указатель на него. - Определяется структура
TSpecializedContainer, которая расширяетTAbstractContainerи добавляет переменнуюnextдля хранения указателя на следующий элемент в связанном списке. - Определяется функция
PushToSpecializedContainer, которая имитирует методPushдляTSpecializedContainer. - Определяется функция
CreateSpecializedContainer, которая создает экземплярTSpecializedContainerи возвращает указатель на него. - В функции
mainсоздаются экземплярыTAbstractContainerиTSpecializedContainer. - Метод
Pushвызывается дляTAbstractContainerс аргументом 13. - Метод
Pushвызывается дляTSpecializedContainerс аргументом 444. - Функция
mainвозвращает 0, что означает успешное завершение программы.