Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. What's the closest thing to anonymous function pointers I can achieve that compiles with GCC?

What's the closest thing to anonymous function pointers I can achieve that compiles with GCC?

Scheduled Pinned Locked Moved C / C++ / MFC
csharpc++data-structurestools
12 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A arnold_w

    I am writing code for an ARM processor and compiling with GCC. I have done some C# programming and there you're allowed to declare delegates inside structures. What's the closest thing I can achieve the same thing in my ARM-project? For example, it would great if I could write a state machine like this:

    typedef void (*readDataResultCallback_t)(uint8_t* readData, uint16_t sizeOfReadData);

    typedef enum {
    STATE1 = 0,
    STATE2 = 1,
    STATE3 = 2,
    } stateMachineState_e;

    typedef struct __attribute__((__packed__)) {
    stateMachineState_e state;
    uint32_t startAddr;
    uint16_t numRegsToRead;
    readDataResultCallback_t readDataResultCallback;
    } stateMachineStep_s;

    static stateMachineState_e state = STATE1;

    stateMachineStep_s stateMachineSteps[3] = {
    {STATE1, 10, 2, { (uint8_t* readData, uint16_t sizeOfReadData) {
    if (stringCompare(readData, "AB") {
    ... Do stuff here...
    state = STATE_2;
    } else {
    ... Do stuff here...
    state = STATE_3;
    }}},
    {STATE2, 20, 3, { (uint8_t* readData, uint16_t sizeOfReadData) {
    if (stringCompare(readData, "ABC") {
    ... Do stuff here...
    state = STATE_1;
    } else {
    ... Do stuff here...
    state = STATE_3;
    }}},
    {STATE3, 30, 4, { (uint8_t* readData, uint16_t sizeOfReadData) {
    if (stringCompare(readData, "ABCD") {
    ... Do stuff here...
    state = STATE_3;
    } else {
    ... Do stuff here...
    state = STATE_2;
    }}},
    };

    Do I need to write my own pre-compile code interpreter/generator script that would place the anonymous code in functions outside the stateMachineStep_s array or is there something clever I can do (perhaps with macros or C++)?

    J Offline
    J Offline
    Josh Gray2
    wrote on last edited by
    #2

    the

    readDataResultCallback

    member of your structure is just a fancy pointer, either 32 or 64 bits long depending on your architecture, so it can only be initialised with the memory address of a function. So you could have something like the following...

    void OnState1(uint8_t* readData, uint16_t sizeOfReadData)
    {
    ...
    }

    stateMachineStep_s stateMachineSteps[3] = {
    {STATE1, 10, 2, &OnState1}
    ...
    }

    which, to be honest, is not significantly more typing. You could also use macros to generate some of the code but that comes with it's own issues. C++11 and greater support lambda expressions which will allow you to initialise your structs with a similar syntax to your example but in that case you would have to swap your function pointer to an std::function<> type. If you don't have c++11 support the boost library offers a similar function pointer but without the nicer lambda syntax.

    A 1 Reply Last reply
    0
    • J Josh Gray2

      the

      readDataResultCallback

      member of your structure is just a fancy pointer, either 32 or 64 bits long depending on your architecture, so it can only be initialised with the memory address of a function. So you could have something like the following...

      void OnState1(uint8_t* readData, uint16_t sizeOfReadData)
      {
      ...
      }

      stateMachineStep_s stateMachineSteps[3] = {
      {STATE1, 10, 2, &OnState1}
      ...
      }

      which, to be honest, is not significantly more typing. You could also use macros to generate some of the code but that comes with it's own issues. C++11 and greater support lambda expressions which will allow you to initialise your structs with a similar syntax to your example but in that case you would have to swap your function pointer to an std::function<> type. If you don't have c++11 support the boost library offers a similar function pointer but without the nicer lambda syntax.

      A Offline
      A Offline
      arnold_w
      wrote on last edited by
      #3

      Josh Gray2 wrote:

      which, to be honest, is not significantly more typing

      It's not a matter of typing less, it's a matter of having code that is easy to read (I expect to have arount 50-60 states).

      Josh Gray2 wrote:

      If you don't have c++11 support the boost library offers a similar function pointer but without the nicer lambda syntax.

      When I googled it, it seems GCC has terrific support for C++.

      Josh Gray2 wrote:

      C++11 and greater support lambda expressions which will allow you to initialise your structs with a similar syntax to your example but in that case you would have to swap your function pointer to an std::function<> type.

      Could someone knowledgeable in C++ please help with the syntax for the example I provided? Do I need to put it inside a C++ file or it is possible have sections of a C-file containing C++ code?

      K L J 3 Replies Last reply
      0
      • A arnold_w

        Josh Gray2 wrote:

        which, to be honest, is not significantly more typing

        It's not a matter of typing less, it's a matter of having code that is easy to read (I expect to have arount 50-60 states).

        Josh Gray2 wrote:

        If you don't have c++11 support the boost library offers a similar function pointer but without the nicer lambda syntax.

        When I googled it, it seems GCC has terrific support for C++.

        Josh Gray2 wrote:

        C++11 and greater support lambda expressions which will allow you to initialise your structs with a similar syntax to your example but in that case you would have to swap your function pointer to an std::function<> type.

        Could someone knowledgeable in C++ please help with the syntax for the example I provided? Do I need to put it inside a C++ file or it is possible have sections of a C-file containing C++ code?

        K Offline
        K Offline
        k5054
        wrote on last edited by
        #4

        arnold_w wrote:

        Could someone knowledgeable in C++ please help with the syntax for the example I provided? Do I need to put it inside a C++ file or it is possible have sections of a C-file containing C++ code?

        You can't put C++ code inside a C file, but since C++ is (mostly) a superset of C, most C code will compile without issue. About the only thing you can't do is use a C identifier that is a C++ keyword (e.g. int new; will not compile in C++). Depending on what you're running on your ARM, you might be able to get C# (mono) up and running on your ARM device (e.g. raspberry pi or similar).

        Keep Calm and Carry On

        1 Reply Last reply
        0
        • A arnold_w

          Josh Gray2 wrote:

          which, to be honest, is not significantly more typing

          It's not a matter of typing less, it's a matter of having code that is easy to read (I expect to have arount 50-60 states).

          Josh Gray2 wrote:

          If you don't have c++11 support the boost library offers a similar function pointer but without the nicer lambda syntax.

          When I googled it, it seems GCC has terrific support for C++.

          Josh Gray2 wrote:

          C++11 and greater support lambda expressions which will allow you to initialise your structs with a similar syntax to your example but in that case you would have to swap your function pointer to an std::function<> type.

          Could someone knowledgeable in C++ please help with the syntax for the example I provided? Do I need to put it inside a C++ file or it is possible have sections of a C-file containing C++ code?

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #5

          There is no syntax for your example, as neither C nor C++ have such a feature. A function pointer needs to contain the address of the function to be called.

          1 Reply Last reply
          0
          • A arnold_w

            Josh Gray2 wrote:

            which, to be honest, is not significantly more typing

            It's not a matter of typing less, it's a matter of having code that is easy to read (I expect to have arount 50-60 states).

            Josh Gray2 wrote:

            If you don't have c++11 support the boost library offers a similar function pointer but without the nicer lambda syntax.

            When I googled it, it seems GCC has terrific support for C++.

            Josh Gray2 wrote:

            C++11 and greater support lambda expressions which will allow you to initialise your structs with a similar syntax to your example but in that case you would have to swap your function pointer to an std::function<> type.

            Could someone knowledgeable in C++ please help with the syntax for the example I provided? Do I need to put it inside a C++ file or it is possible have sections of a C-file containing C++ code?

            J Offline
            J Offline
            Josh Gray2
            wrote on last edited by
            #6

            arnold_w wrote:

            Could someone knowledgeable in C++ please help with the syntax for the example I provided? Do I need to put it inside a C++ file or it is possible have sections of a C-file containing C++ code?

            #include typedef std::function readDataResultCallback_t;

            typedef struct __attribute__((__packed__)) {
            stateMachineState_e state;
            uint32_t startAddr;
            uint16_t numRegsToRead;
            readDataResultCallback_t readDataResultCallback;
            } stateMachineStep_s;

            stateMachineStep_s stateMachineSteps[3] = {
            {STATE1, 10, 2, [](uint8_t* readData, uint16_t sizeOfReadData) {
            if (stringCompare(readData, "AB") {
            ... Do stuff here...
            state = STATE_2;
            } else {
            ... Do stuff here...
            state = STATE_3;
            }},
            ...

            1 Reply Last reply
            0
            • A arnold_w

              I am writing code for an ARM processor and compiling with GCC. I have done some C# programming and there you're allowed to declare delegates inside structures. What's the closest thing I can achieve the same thing in my ARM-project? For example, it would great if I could write a state machine like this:

              typedef void (*readDataResultCallback_t)(uint8_t* readData, uint16_t sizeOfReadData);

              typedef enum {
              STATE1 = 0,
              STATE2 = 1,
              STATE3 = 2,
              } stateMachineState_e;

              typedef struct __attribute__((__packed__)) {
              stateMachineState_e state;
              uint32_t startAddr;
              uint16_t numRegsToRead;
              readDataResultCallback_t readDataResultCallback;
              } stateMachineStep_s;

              static stateMachineState_e state = STATE1;

              stateMachineStep_s stateMachineSteps[3] = {
              {STATE1, 10, 2, { (uint8_t* readData, uint16_t sizeOfReadData) {
              if (stringCompare(readData, "AB") {
              ... Do stuff here...
              state = STATE_2;
              } else {
              ... Do stuff here...
              state = STATE_3;
              }}},
              {STATE2, 20, 3, { (uint8_t* readData, uint16_t sizeOfReadData) {
              if (stringCompare(readData, "ABC") {
              ... Do stuff here...
              state = STATE_1;
              } else {
              ... Do stuff here...
              state = STATE_3;
              }}},
              {STATE3, 30, 4, { (uint8_t* readData, uint16_t sizeOfReadData) {
              if (stringCompare(readData, "ABCD") {
              ... Do stuff here...
              state = STATE_3;
              } else {
              ... Do stuff here...
              state = STATE_2;
              }}},
              };

              Do I need to write my own pre-compile code interpreter/generator script that would place the anonymous code in functions outside the stateMachineStep_s array or is there something clever I can do (perhaps with macros or C++)?

              CPalliniC Offline
              CPalliniC Offline
              CPallini
              wrote on last edited by
              #7

              If you are allowed to use (a modern version of) the C++ compiler (g++), then something like this

              #include
              #include
              using namespace std;

              using MyCallback = function ;

              struct State
              {
              int i;
              MyCallback mc;
              };

              State s[] =
              {
              { 10, [](const char * p, size_t size ){ for (size_t n=0; n
              would work.

              In testa che avete, signor di Ceprano?

              A 2 Replies Last reply
              0
              • CPalliniC CPallini

                If you are allowed to use (a modern version of) the C++ compiler (g++), then something like this

                #include
                #include
                using namespace std;

                using MyCallback = function ;

                struct State
                {
                int i;
                MyCallback mc;
                };

                State s[] =
                {
                { 10, [](const char * p, size_t size ){ for (size_t n=0; n
                would work.

                A Offline
                A Offline
                arnold_w
                wrote on last edited by
                #8

                I converted my project to a C++ project (I could see that the line org.eclipse.cdt.core.ccnature got added inside my .project file) and added your code, but I get the following error message when I try to build the project: cannot open linker script file -Wl,-Map=output.map: No such file or directory MyProject C/C++ Problem Do you know what I'm doing wrong?

                L 1 Reply Last reply
                0
                • A arnold_w

                  I converted my project to a C++ project (I could see that the line org.eclipse.cdt.core.ccnature got added inside my .project file) and added your code, but I get the following error message when I try to build the project: cannot open linker script file -Wl,-Map=output.map: No such file or directory MyProject C/C++ Problem Do you know what I'm doing wrong?

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #9

                  The option format is incorrect, it should be -Wl,-Map,output.map as described at Link Options (Using the GNU Compiler Collection (GCC))[^].

                  A 1 Reply Last reply
                  0
                  • L Lost User

                    The option format is incorrect, it should be -Wl,-Map,output.map as described at Link Options (Using the GNU Compiler Collection (GCC))[^].

                    A Offline
                    A Offline
                    arnold_w
                    wrote on last edited by
                    #10

                    So I went to Project Properties -> C/C++ Build -> Settings -> MCU G++ Linker and replaced the following Command line pattern:

                    ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}

                    with

                    arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -T"" -Wl,-Map,output.map -Wl,--gc-sections -fno-exceptions -fno-rtti -o "MyProject.elf" @"objects.list" -lm

                    When I build the project and look inside the console window, I see the following:

                    Invoking: MCU G++ Linker
                    arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -T"" -Wl,-Map,output.map -Wl,--gc-sections -fno-exceptions -fno-rtti -o "MyProject.elf" @"objects.list" -lm -lm
                    c:/ac6/systemworkbench/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.17.0.201812190825/tools/compiler/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld.exe: cannot open linker script file -Wl,-Map,output.map: No such file or directory

                    What did I do wrong?

                    L 1 Reply Last reply
                    0
                    • A arnold_w

                      So I went to Project Properties -> C/C++ Build -> Settings -> MCU G++ Linker and replaced the following Command line pattern:

                      ${COMMAND} ${FLAGS} ${OUTPUT_FLAG} ${OUTPUT_PREFIX}${OUTPUT} ${INPUTS}

                      with

                      arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -T"" -Wl,-Map,output.map -Wl,--gc-sections -fno-exceptions -fno-rtti -o "MyProject.elf" @"objects.list" -lm

                      When I build the project and look inside the console window, I see the following:

                      Invoking: MCU G++ Linker
                      arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -T"" -Wl,-Map,output.map -Wl,--gc-sections -fno-exceptions -fno-rtti -o "MyProject.elf" @"objects.list" -lm -lm
                      c:/ac6/systemworkbench/plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.17.0.201812190825/tools/compiler/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/bin/ld.exe: cannot open linker script file -Wl,-Map,output.map: No such file or directory

                      What did I do wrong?

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #11

                      arnold_w wrote:

                      What did I do wrong?

                      Nothing that I can see. I just did a build with -Wl,-Map,output.map and it worked fine. But the error message you have suggests that the linker is trying to read -Wl,-Map,output.map as a script file for some reason. I am not sure whether the MCU g++ linker is significantly different from the standard ld linker, but you may want to check the documentation.

                      1 Reply Last reply
                      0
                      • CPalliniC CPallini

                        If you are allowed to use (a modern version of) the C++ compiler (g++), then something like this

                        #include
                        #include
                        using namespace std;

                        using MyCallback = function ;

                        struct State
                        {
                        int i;
                        MyCallback mc;
                        };

                        State s[] =
                        {
                        { 10, [](const char * p, size_t size ){ for (size_t n=0; n
                        would work.

                        A Offline
                        A Offline
                        arnold_w
                        wrote on last edited by
                        #12

                        It's probably a stupid question, but is there any way to make anonymous function usage like that compile inside a file with .c (not .cpp) extension? I know I'm allowed to put snippets of C-code inside a C++ file, but I suppose the opposite isn't possible (not even with clever macros)?

                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        • Login

                        • Don't have an account? Register

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • World
                        • Users
                        • Groups