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.
  • 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