Having quite big codebase and external libraries, in C application,what would be pros and cons of two approaches (or suggest other):(assume that there are NONE api provided calls for this)Edit from comment: Goal is to select nicer approach in long term - for manipulation of some elements from engine etc, where some elements might belong to GUI, or other module (both conceptually, from other translation module, separated to put it in one word).pass pointer to struct containing various pointers for some gui labels, buttons, etc, to engine, and later = to every engine function that needs to manipulate those items. keep global static handles to some gui labels, buttons, etc in gui_help.c, initialized by gui - and provide access to them with some getter(name_what) exposed from gui_help.hMinimal example (removed header guardians, mem management, error checks etc):Scroll below this for quick Python snipplet to setup exact of below locally.// ## main.c ###include gui.hint main(int argc, char *argv[]){    gui();    return 0;}// ## gui.h ##void gui();typedef struct { int many_variables_and_pointers; } gui_struct; // ## gui.c ###include gui.h#include gui_help.h#include engine.hvoid gui(){    gui_struct gs;    gs.many_variables_and_pointers = init_a_from_gui_help();    //gs.other_variables_and_pointers = init_b_from_gui_help();    //...foo, bar    // engine callbacks are registered here.    // GUI LOOPS here in engine event loop, other threads handle user interaction.    engine_loop();}// ## gui_help.h ##init_a_from_gui_help();//init_b_from_gui_help();// ## gui_help.c ##int init_a_from_gui_help(){    return 42;}// ## engine.h ##void engine_loop();void some_engine_callback_example_1(void* data);void some_engine_callback_example_2();// ## engine.c ##void engine_loop(){    volatile int a;    while(1){        a = 1;    }    printf(%d, a);}void some_engine_callback_example_1(void* data){    // data->some_gui_element->manipulate();    // would require initializing struct data with gui elements,    // and passing pointer to this struct from engine to any other call,    // possibly nesting several stack levels, limiting somewhat encapsulation    // Possible synchronization issues as well?}void some_engine_callback_example_2(){    // my_local_gui_element_pointer_copy = getter(label1);    // my_local_gui_element_pointer_copy.manipulate();    // would require #include gui_help.h, exposing api,     // and keeping static global handles to labels, buttons, etc.}Python snipplet to setup this locally, compacted to prevent scrolling this page even more.# Python - THIS CODE GENERATES ABOVE STRUCTURE, for easier browsing. Run in new dir.a = [main.c, gui.h, gui.c, gui_help.h, gui_help.c, engine.h, engine.c]main_c =  #include gui.h\nint main(int argc, char *argv[]){\ngui();\nreturn 0;\n}gui_h = void gui();\ntypedef struct {int many_variables_and_pointers;} gui_struct;gui_c = #include gui.h\n#include gui_help.h\n#include engine.h\nvoid gui(){\n    gui_struct gs;\ngs.many_variables_and_pointers = init_a_from_gui_help();\n    \n//gs.other_variables_and_pointers = init_b_from_gui_help();\n//...foo, bar\n// engine callbacks are registered here.\n// GUI LOOPS here in engine event loop, other threads handle user interaction.\nengine_loop();\n}gui_help_h = init_a_from_gui_help();\n//init_b_from_gui_help();gui_help_c = int init_a_from_gui_help(){\n   return 42;\n}engine_h = void engine_loop();\nvoid some_engine_callback_example_2();\nvoid some_engine_callback_example_1(void* data);engine_c = void engine_loop(){\n\tvolatile int a;\n\twhile(1){\n\t\ta = 1;\n\t}\n\tprintf(%d, a);\n}\nvoid some_engine_callback_example_1(void* data){\n\t// data->some_gui_element->manipulate();\n\t// would require initializing struct data with gui elements,\n\t// and passing pointer to this struct from engine to any other call,\n\t// possibly nesting several stack levels, limiting somewhat encapsulation\n\t// Possible synchronization issues as well?\n\t}\nvoid some_engine_callback_example_2(){\n\t// my_local_gui_element_pointer_copy = getter(label1);\n\t// my_local_gui_element_pointer_copy.manipulate();\n\t// would require #include gui_help.h, exposing api, \n\t// and keeping static global handles to labels, buttons, etc.\n\t}b = [main_c, gui_h, gui_c, gui_help_h, gui_help_c, engine_h, engine_c]for i, filename in enumerate(a):    with open(filename, 'w') as file_:        file_.write(b[i])
GUI - engine data exchange, design with C, getters or struct pointers passing?
design;c;object oriented design;gui