Thread: function pointers

  1. #1
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174

    function pointers

    I'm working on a "Menu Manager" that will let me display menus that are saved as a text file. This way I can add or remove menu items without having to recompile the whole program. The problem I am having is how to match the menu items that are read from the text file to the actual function calls. After reading around a bit I figure the best way to do this is to use a std::map to map the menu items with pointers to the correct function. So I figure I could parse through the text file, extracting each menu item and mapping a function pointer to it. However, I would still have to recompile the file eveytime I change a menu so that the correct function pointers would be mapped.

    Is there a better way to do this using c++ or am I just stuck using a bunch of if/then statements and changing it everytime I add or remove menu items?
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

  2. #2
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    How can you add a menu option without adding code that actually does what the menu option says? So you have to recompile the program anyway.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Seems to me the code would simply add all known menu-string, function-pointer pairs to the map at start up. The end user would have to select from the list of all known menu-items. If you add a new menu-string, then obviously you'll need to add it to the map, with a supporting function pointer.

    gg

  4. #4
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Two ways I can think of:

    First, like you said, mapping ALL possible calls, like:
    Code:
    somemap["new"] = &menu_func_new;
    somemap["save"] = &menu_func_save;
    etc, and simply retrieving the function from there. However, the number of possibilities is limited.

    Another way is to implement your own programming language, your own interpreter. Prepare to spend months on that though .

    The last method is to have something like DLLs or SO-files that will be inserted by the project. Then you only have to recompile the DLL/SO to change the menu item.

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Another way is to implement your own programming language, your own interpreter. Prepare to spend months on that though .
    Yet another way would be to use an existing language capable of that
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  6. #6
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174
    Right. So if I am having to go in and map all the menu string-function pointer pairs anyway, then is there any point in having the external text file? Seems like it would be just as easy to hard code everything and not have to ess with the text file at all. The more I think about it the more it seems like this "Menu Manager" thing is kind of pointless.
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

  7. #7
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174
    Quote Originally Posted by anon View Post
    Yet another way would be to use an existing language capable of that
    I have looked into other laguages that do support this but (for now) I kinda want to stick to C/C++ until I have a better understanding of the language.
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Whatever you do, don't implement yet another scripting language for that!!

    I would actually be quite satisfied with a menu management system (classes for displaying and receiving input and perhaps notifying respective handlers) that let you easily plug in menu options at code level (and perhaps disable some at runtime). Although it might be possible indeed to load the code dynamically from DLL's that can be added at any time (aren't DLL's called through function names in string format?). Your hands will still probably be more tied than with a scripting language with introspection support...
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by anon View Post
    ...(aren't DLL's called through function names in string format?)...
    Yeah, that's possible. You can dynamically find if a DLL has a function with a specific name and call it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The only use I can think of for the menu system is rearranging existing options.

    A more interesting project would be a menu system library that allows you to specify the menu in C++ code, but in a declarative fashion. Look at the usage of the Boost.ProgramOptions library to see what I mean.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  11. #11
    Registered User
    Join Date
    Jan 2009
    Posts
    31
    Quote Originally Posted by Dark_Phoenix View Post
    Right. So if I am having to go in and map all the menu string-function pointer pairs anyway, then is there any point in having the external text file? Seems like it would be just as easy to hard code everything and not have to ess with the text file at all. The more I think about it the more it seems like this "Menu Manager" thing is kind of pointless.
    Well, it would allow users to customize the user interface. One use could be internationalization (different languages for menus). You could go a step further to include accelerator keys, and possibly toolbar items, if applicable. All of these would have actions specified by the same set of action identifiers (the strings in the aforementioned map). Plugins could expose their actions through the same interface (via. registration with an action manager), so actions not built into the menus could also be customized. It does make much more sense in conjunction with an application hosted programming environment though. All of the programs that I've used with this feature also include a hosted programming language or environment of some sort.

  12. #12
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    [edit] That's pretty funny! I didn't notice you'd mentioned it, but notice the accelerator key "lshift f10" in the XML file below . . .
    All of these would have actions specified by the same set of action identifiers (the strings in the aforementioned map). Plugins could expose their actions through the same interface (via. registration with an action manager), so actions not built into the menus could also be customized.
    That's precisely the kind of thing in mind when I created this part of xuni.
    [/edit]

    In case you're interested, I did something quite similar to this with my project xuni. Basically, different menus or screens could be specified in .so files, which could then be loaded by name.

    I added support for loading .so files using the SDL, and using just libdl, and using hard-coded names in case neither of these was supported. (I never implemented Windows support for this, unfortunately; I just used static names on Windows.) The code for this is in src/loadso.c and src/loadso.h (you can download xuni's source from here).

    Menus were specified in XML files; here's a sample of one.
    Code:
    <?xml version="1.0"?>
    <!-- gui/data/game.xml -->
    <xuni-resource xuni-version="0.3.0" type="gui-data">
        <widget type="panel" name="game">
            <width>100</width>
            <height>100</height>
            <visible>0</visible>
            
            <handler file="src/test/libtest.so">
                <init>game_init</init>
                <start>game_start</start>
                <event>game_event</event>
                <click>game_click</click>
                <paint>game_paint</paint>
                <free>game_free</free>
            </handler>
            
            <widget type="image">
                <name>background 1</name>
                <xpos>0</xpos>
                <ypos>0</ypos>
                <width>100</width>
                <height>100</height>
                <path>../background/m31.jpg</path>
                <selable>0</selable>
            </widget>
            
            <widget type="button">
                <name>menu</name>
                <xpos>100.0 - 100.0 / 8</xpos>
                <ypos>0</ypos>
                <width>100.0 / 8</width>
                <height>100.0 / 15</height>
                <text>Menu</text>
                <accelerator>lshift f10</accelerator>
            </widget>
            
            <widget type="button">
                <name>layer 1</name>
                <xpos>30</xpos>
                <ypos>30</ypos>
                <width>20</width>
                <height>10</height>
                <text>1</text>
            </widget>
    
    ...
    As you can see, handler functions for certain actions are specified by name, along with the library in which those functions are found. These handlers would then reference widgets in the menu by name.

    I don't think I ever got to the point where you could add an entirely new menu without adding at least another enum value, but you certainly could if you put your mind to it. One tip: consider always using strings. I opted out of that for efficiency reasons, but it made the code much harder to understand and less flexible.

    My code is probably way too confusing for you, but it's so similar to this that I just had to mention it. If you're interested, feel free to ask me more questions about it.

    Disclaimer: xuni's code isn't the most readable, and it is in C (not C++), so it's not as simple as it could be. This is the kind of thing that C++ lends itself really well to.
    Last edited by dwks; 02-28-2009 at 06:55 PM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  13. #13
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174
    Quote Originally Posted by anon
    I would actually be quite satisfied with a menu management system (classes for displaying and receiving input and perhaps notifying respective handlers) that let you easily plug in menu options at code level (and perhaps disable some at runtime). Although it might be possible indeed to load the code dynamically from DLL's that can be added at any time (aren't DLL's called through function names in string format?). Your hands will still probably be more tied than with a scripting language with introspection support...
    This sounds interesting. I don't have any experience with creating and using DLL's but this could be good project for me to gain some more knowledge with.
    So in theory I could create a basic menu manager system that could take an external text file containing a list of menu items and related function names and map those together, and then have a seperate DLL with the function implementations. Changing the menu structure would be as easy as changing the text file. The manager could then also handle all user input and handler notifications. I could even implement some sort of restriction based on user level.

    Quote Originally Posted by dwks
    In case you're interested, I did something quite similar to this with my project xuni.
    This seems interesting as well. I will have to look into this when I have more time
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  2. Problem with function pointers
    By vNvNation in forum C++ Programming
    Replies: 4
    Last Post: 06-13-2004, 06:49 AM
  3. Staticly Bound Member Function Pointers
    By Polymorphic OOP in forum C++ Programming
    Replies: 29
    Last Post: 11-28-2002, 01:18 PM
  4. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM
  5. function pointers and member functions
    By thor in forum C++ Programming
    Replies: 5
    Last Post: 03-19-2002, 04:22 PM