модульні підходи загалом досить зручні (портативні та чисті), тому я намагаюся програмувати модулі настільки незалежно від будь-яких інших модулів, наскільки це можливо. Більшість моїх підходів базується на структурі, яка описує сам модуль. Функція ініціалізації задає основні параметри, після чого оброблювач (покажчик на дескриптивну структуру) передається будь-якій функції в модулі.
Наразі мені цікаво, яким може бути найкращий підхід до розподілу пам'яті для структури, що описує модуль. Якщо можливо, я хотів би наступного:
- Непрозора структура, тому структура може бути змінена лише за допомогою наданих функцій інтерфейсу
- Кілька примірників
- пам'ять, виділена лінкером
Я бачу такі можливості, що всі суперечать одній із моїх цілей:
глобальна декларація
декілька екземплярів, нанесених на лінкер, але структура непрозора
(#includes)
module_struct module;
void main(){
module_init(&module);
}
малок
непрозора структура, декілька примірників, але всебічне нагромадження
в module.h:
typedef module_struct Module;
у module.c функція init, malloc та вказівник повернення на виділену пам'ять
module_mem = malloc(sizeof(module_struct ));
/* initialize values here */
return module_mem;
в main.c
(#includes)
Module *module;
void main(){
module = module_init();
}
декларація в модулі
непрозора структура, виділена лінкером, лише заздалегідь визначена кількість примірників
зберігайте всю структуру та пам'ять всередині модуля і ніколи не піддавайте обробник або struct.
(#includes)
void main(){
module_init(_no_param_or_index_if_multiple_instances_possible_);
}
Чи є можливість комбінувати їх якось для непрозорої структури, лінкера замість розподілу купи та декількох / будь-якої кількості екземплярів?
рішення
як запропоновано в деяких відповідях нижче, я думаю, що найкращим способом є:
- резервного місця для MODULE_MAX_INSTANCE_COUNT модулів у вихідному файлі модулів
- не визначайте MODULE_MAX_INSTANCE_COUNT у самому модулі
- додати #ifndef MODULE_MAX_INSTANCE_COUNT #error у файл заголовка модулів, щоб переконатися, що користувач модулів знає про це обмеження та визначає максимальну кількість бажаних екземплярів для програми
- при ініціалізації екземпляра повертайте або адресу пам'яті (* void) описової структури, або індекс модулів (все, що вам більше подобається)