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 Offline
    A Offline
    arnold_w
    wrote on last edited by
    #1

    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 CPalliniC 2 Replies 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++)?

      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