0

I have one application in which following task are to be done

1.) UI application will send command code (integer value).
2.) DLL interface(in c++) will get that integer value and execute corresponding command function.

commands name and command code are maintained as

#define PING 50

there will be 500 commands and applying SWITCH CASE will not sound good. so i decided to implement function pointer in my code as below

   #include "stdafx.h"

    #include<iostream>
    #define PING 20

    using namespace std;
    //extern const int PING = 10; 
    void ping()
    { 
                    cout<<"ping command executed";
    }


    void get_status(void)
    {


    cout<<"Get_status called"<<endl;

    }

    class ToDoCommands
    {
            public:
                void getCommand( void (*CommandToCall)() );                         
    };



    void ToDoCommands::getCommand( void (*CommandToCall)())
    {


        void (*CommandToCall1)();

        CommandToCall1  = CommandToCall;

        CommandToCall1();

    }

    int main()
    {
            int code;
            ToDoCommands obj;
            cout<<"enter command code";
            cin>>code;  // if UI send 50 then Ping function get executed as #define PING 50

            obj.getCommand(ping);   // here m passing ping manually..
            //obj.getCommand(get_status);

                return 0;
    }

how can i pass command name corresponding to command code in

obj.getCommand(ping); 
2
  • Are the command values defined, or can you pick whichever numbers you like? Commented Sep 17, 2012 at 10:31
  • yeah command values are defined and fixed Commented Sep 17, 2012 at 10:32

3 Answers 3

3

You are almost there: make a std::map of std::string to function pointer, initialize it with data pairing a string name to a corresponding function pointer, and then use that map at runtime to pick the correct pointer based on the string parameter passed in.

#include <iostream>
#include <string>
#include <map>

using namespace std;

void ping() {
    cout << "ping" << endl;
}
void test() {
    cout << "test" << endl;
}
int main() {
    map<string,void(*)()> m;
    m["ping"] = ping;
    m["test"] = test;
    // I am using hard-coded constants below.
    // In your case, strings will come from command line args
    m["test"]();
    m["ping"]();
    return 0;
}

Link to a demo with std::map.

Here is how you can do it without a map (it will be slower because of the linear search, but you can fix it by ordering names alphabetically and using binary search).

#include <iostream>
#include <cstring>

using namespace std;

void ping() {
    cout << "ping" << endl;
}
void test() {
    cout << "test" << endl;
}
typedef void (*fptr_t)();
int main() {
    const fptr_t fptrs[] = {test, ping};
    const char *names[] = {"test", "ping"};
    const char *fname = "test";
    for (int i = 0 ; i != 2 ; i++) {
        if (!strcmp(fname, names[i])) {
            fptrs[i]();
            break;
        }
    }
    return 0;
}

Link to a demo with arrays.

Sign up to request clarification or add additional context in comments.

9 Comments

@james What do you mean? You use strings already, there's nothing wrong with adding a map. Nobody will be able to tell that you use STL in your dll.
this dll will be linked with C# and IOs application and also it wont work under linux environment...so i need arrays instead of map
@james Needing arrays instead of a map is not a problem. Can you at least use std::pair?
@james: Is it possible that you don't want to use the STL in functions exported from your DLL because STL does some memory allocations/deallocations (a no-no across DLL boundaries)? If so, you could have the STL as an implementation detail of your DLL and simply expose a void invoke(const char *fn) function.
@NiravMadhani C++ has no reflection capabilities: once the code is compiled, all the names are thrown away.
|
0

Declare an array of function pointers. Where you treat the index as your "code". For example:

void foo(){
    printf("foo\n");
}

void bar(){
    printf("bar\n");
}

int main(void)
{
    void (*code_to_function[100])();
    int code;

    code_to_function[0] = foo;
    code_to_function[1] = bar;
    printf("Enter code: ");
    scanf("%d", &code);
    code_to_function[code]();

    return 0;
}

Please note that for this rudimentary example, inputting integer code other than 0 and 1 will result in a segfault.

Comments

0

I should say @dasblinkenlight is right but if you don't want to use std::map you should implement a map yourself. This can be buggy and not a optimized way, but if you don't want to use STL, it seems you should implement it yourself.

You can use 2 arrays with corresponding indices. One of them is a char * array and another one is function pointers. They are better to be encapsulated in a class named something like MyMap.

class MyMap {
  public:
    ...

    inline void add(char *name, (void (*ptr)(void)) ) {
      names_[currIndex_] = name; // Or stcpy
      ptrs_[currIndex_] = ptr;
      currIndex_++;
    }

    inline (void(*)(void)) get(char *name) {
      int foundIndex = -1;
      for (int i = 0; i < currIndex_; i++) {
        // Find matching index
      }
      if (foundIndex_ >= 0) {
        return ptrs_[foundIndex_];
      }
      return NULL;
    }

  private:
    int currIndex_;
    char *names_[10];
    (void (*ptrs_[10])(void));
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.