Lets say I have several functions like function1(), function2(), ....., function1000()
and I am getting a string in a function lets say call_function(string function_name).
Now I need to execute function based on function_name.
I searched for solutions and found I can use maps.
Is there any easy way to create a map for lets say 1000 keys(string type) and respective functions ?
eg: call_function(function541) then it should execute function541();
You can use map to function pointers for this stuff
void func1(const char *args)
{
//....
}
void func2(const char *args)
{
//....
}
typedef void (*function) (const char *args);
//......
std::map<std::string, function> func_map;
func_map.insert(std::pair<std::string, function>("func1", func1));
func_map.insert(std::pair<std::string, function>("func2", func2));
func_map["func1"]("arg1 arg2 arg3"); // Here is the func1 call
Is there any easy way to create a map for lets say 1000 keys(string type) and respective functions ?
eg: call_function(function541)
then it should execute function541();
No, there is no easy way, because C++ does not have reflection. Function names only exist for the compiler. At run-time, there is no relationship between a function called function541 in your source code and the string "function541" existing in memory while the program is being executed.
Each and any of such links must be established manually:
std::map<std::string, std::function<void()>> map;
// ...
map["function541"] = function541;
Of course, you can still automate such a task with code generation. Functions with mechanical names like this don't look like manually written C++ code anyway. That is, you can write a script in some other language that creates the C++ code to add the thousand functions to the map, perhaps as some kind of pre-build step.
Still, from a run-time point of view, there's no automation whatsoever.
Related
I am writing an adapter to combine two APIs (one in C and another in C++).
If a function is called on the one API I need to pass the callers ID and the function's arguments to an adapter and call the according function with this information passed.
Now aparently they can not be mapped directly as one interface requires C++ compilation and the name mangling would screw the other so that is why I am using a set of adapters in the first place.
As the number of arguments varies, I looked up variadic functions and found the idea pretty useful, however I am operating on POD only and have to deal with structs, enums and a lot of different arguments per call, which might need to be put back into a struct before feeding it to the target function.
Every example I stumbled upon was far simpler and involved mostly arithmetic operations like summing stuff up , finding largest numbers or printing. Mostly done with for loops on the var_list.
Maybe I got stuck on the idea and it won't work at all, but I am just curious...
Say I wanted to assign the arguments from the list to my target functions parameters (the order of the arguments passed is the correct one), what would be a good way?
BOOL Some_Function(
/* in */ CallerId *pObjectId,
/* in */ someDataType argument1 )
{
BOOL ret = Adapter_Call(pFunction, pObjectId, argument1);
return ret;
}
and so once I made it to the right adapter I want to do
BOOL Adapter_Call(*pFunction, *pObjectId, argument1, ...)
{
va_list args;
va_start(args, argument1);
/*go over list and do `var_list[i] = pFunctionArgList[i]` which is
of whatever type so I can use it as input for my function */
va_end(args);
pObjectId.pFunction(arg1,...,argn);
}
Can I access the input parameters of a function to perform assignments like this?
Has anyone done something like this before? Is there a conceptual mistake in my thinking?
All I found on the net was this, http://www.drdobbs.com/cpp/extracting-function-parameter-and-return/240000586but due to the use of templates I am not sure if it wouldn't create another problem and so in the end implementing an adapter for each and every single functioncall may be simpler to do.
A SO search only returned this: Dynamic function calls at runtime (va_list)
First, you should heed Kerrek's advice about extern "C". This is C++'s mechanism for giving an identifier C linkage, meaning that the name won't be mangled by the C++ compiler.
Sometimes, and adapter still needs to be written for a C++ interface, because it manipulates objects that do not map to a C POD. So, the adapter gives the C interface a POD or opaque pointer type to manipulate, but the implementation of that interface converts that into an C++ object or reference and then calls the C++ interface. For example, suppose you wanted to provide a C interface for C++ std::map<int, void *>, you would have a common header file in C and C++ that would contain:
#ifdef __cplusplus
extern "C" {
#endif
struct c_map_int_ptr;
// ...
// return -1 on failure, otherwise 0, and *data is populated with result
int c_map_int_ptr_find (struct c_map_int_ptr *, int key, void **data);
#ifdef __cplusplus
}
#endif
Then, the C++ code could implement the function like:
typedef std::map<int, void *> map_int_ptr;
int c_map_int_ptr_find (struct c_map_int_ptr *cmap, int key, void **data) {
map_int_ptr &map = *static_cast<map_int_ptr *>(cmap);
map_int_ptr::iterator i = map.find(key);
if (i != map.end()) {
*data = i->second;
return 0;
}
return -1;
}
Thus, there is no need to pass the arguments passed via the C interface through a variable argument adapter. And so, there is no need for the C++ code to tease out the arguments from a variable argument list. The C code calls directly into the C++ code, which knows what to do with the arguments.
I suppose if you are trying to implement some kind of automated C adapter code generator by parsing C++ code, you could think that using variable arguments would provide a regular mechanism to communicate arguments between the generated C code interface and the generated C++ adapter code that would call the original C++ interface. For such a scenario, the code for the above example would look something like this:
// C interface
typedef struct c_map_int_ptr c_map_int_ptr;
typedef struct c_map_int_ptr_iterator c_map_int_ptr_iterator;
//...
c_map_int_ptr_iterator c_map_int_ptr_find (c_map_int_ptr *map, int key) {
c_map_int_ptr_iterator result;
cpp_map_int_ptr_adapter(__func__, map, key, &result);
return result;
}
// C++ code:
struct cpp_adapter {
virtual ~cpp_adapter () {}
virtual void execute (va_list) {}
};
void cpp_map_int_ptr_adapter(const char *func, ...) {
va_list ap;
va_start(ap, func);
cpp_map_int_ptr_adapter_method_lookup(func).execute(ap);
va_end(ap);
}
//...
struct cpp_map_int_ptr_find_adapter : cpp_adapter {
void execute (va_list ap) {
map_int_ptr *map = va_arg(ap, map_int_ptr *);
int key = va_arg(ap, int);
c_map_int_ptr_iterator *c_iter = va_arg(ap, c_map_int_ptr_iterator *);
map_int_ptr::iterator i = map->find(key);
//...transfer result to c_iter
}
};
Where cpp_map_int_ptr_adapter_method_lookup() returns an appropriate cpp_adapter instance based on a table lookup.
I'm creating a 2D RPG game engine in C++ with Allegro. I've reached the point in which i need to implement a scripting system. So, my poblem is this one:
I have a struct called Event. Inside this struct there is a function pointer, which points to the function that i want to execute when the event is fired. So, here's an example:
struct Event {
//...
void (*func)(Player*, void*);
//...
}
Now, to create an event i have this function:
Event* Events::register_event_source(int x, int y, std::string name, Player* player, void (*func)(Player*, void*));
So, to use it i just need to create a function with this signature:
void test_event(Player* p, void* data)
{
//Do something cool here
}
and then register an event source, giving the address to that function:
//...
Player* player = new Player(0, 0);
//...
Event* evt = Events::register_event_source(10, 10, "test event", player, &test_event);
//Eventually set some data for the event
evt->set_data(new std::string("Just some test data"));
In this way, when the player goes over the assigned spot (in this case x = 10, y = 10) the event will fire, executing any code in the test_event function.
Now, my question is: is it possible to do, or at least to get close to, this process at runtime?? ...i would need to create the function (in this case "test_event") at runtime, but i did some research, and i think what i understood is that it is not really possible to create functions at runtime.
So, which approach should i go for?? ...I know it is an abstract question...but i really don't know how to approach this problem.
Thanks in advice for any help! and sorry for my bad explaining abilities...English is not my language!
If I understand correctly what you are trying to express, you are writing a scripting engine that interprets some logics built at run-time into a string, and this should determine what to do on Player and data. If so, I can imagine you should have a function like
void InterpretScriptCode(Player* p, void* data, string const& code)
or something equivalent that interprets and execute the logics described in code on p and data.
Then, you can use std::bind and std::function to encapsulate a call to your scripting engine:
// Header <functional> needs to be included, and a proper "using namespace"
// directive must be present for bringing placeholders _1 and _2 into scope
std::function<void(Player*, void*)> fxn = std::bind(
&InterpretScriptCode,
_1,
_2,
"int x = 0; ... blah blah" // this should be your run-time generated script
);
And pass fxn in input to your register_event_source() function.
Btw, you might be interested in using Boost.Signals/Boost.Signals2 for realizing event registration/handling.
If you are not using C++11, you can use boost::bind and boost::function instead of std::bind and std::function.
this is my first question after long time checking on this marvelous webpage.
Probably my question is a little silly but I want to know others opinion about this. What is better, to create several specific methods or, on the other hand, only one generic method? Here is an example...
unsigned char *Method1(CommandTypeEnum command, ParamsCommand1Struct *params)
{
if(params == NULL) return NULL;
// Construct a string (command) with those specific params (params->element1, ...)
return buffer; // buffer is a member of the class
}
unsigned char *Method2(CommandTypeEnum command, ParamsCommand2Struct *params)
{
...
}
unsigned char *Method3(CommandTypeEnum command, ParamsCommand3Struct *params)
{
...
}
unsigned char *Method4(CommandTypeEnum command, ParamsCommand4Struct *params)
{
...
}
or
unsigned char *Method(CommandTypeEnum command, void *params)
{
switch(command)
{
case CMD_1:
{
if(params == NULL) return NULL;
ParamsCommand1Struct *value = (ParamsCommand1Struct *) params;
// Construct a string (command) with those specific params (params->element1, ...)
return buffer;
}
break;
// ...
default:
break;
}
}
The main thing I do not really like of the latter option is this,
ParamsCommand1Struct *value = (ParamsCommand1Struct *) params;
because "params" could not be a pointer to "ParamsCommand1Struct" but a pointer to "ParamsCommand2Struct" or someone else.
I really appreciate your opinions!
General Answer
In Writing Solid Code, Steve Macguire's advice is to prefer distinct functions (methods) for specific situations. The reason is that you can assert conditions that are relevant to the specific case, and you can more easily debug because you have more context.
An interesting example is the standard C run-time's functions for dynamic memory allocation. Most of it is redundant, as realloc can actually do (almost) everything you need. If you have realloc, you don't need malloc or free. But when you have such a general function, used for several different types of operations, it's hard to add useful assertions and it's harder to write unit tests, and it's harder to see what's happening when debugging. Macquire takes it a step farther and suggests that, not only should realloc just do _re_allocation, but it should probably be two distinct functions: one for growing a block and one for shrinking a block.
While I generally agree with his logic, sometimes there are practical advantages to having one general purpose method (often when operations is highly data-driven). So I usually decide on a case by case basis, with a bias toward creating very specific methods rather than overly general purpose ones.
Specific Answer
In your case, I think you need to find a way to factor out the common code from the specifics. The switch is often a signal that you should be using a small class hierarchy with virtual functions.
If you like the single method approach, then it probably should be just a dispatcher to the more specific methods. In other words, each of those cases in the switch statement simply call the appropriate Method1, Method2, etc. If you want the user to see only the general purpose method, then you can make the specific implementations private methods.
Generally, it's better to offer separate functions, because they by their prototype names and arguments communicate directly and visibly to the user that which is available; this also leads to more straightforward documentation.
The one time I use a multi-purpose function is for something like a query() function, where a number of minor query functions, rather than leading to a proliferation of functions, are bundled into one, with a generic input and output void pointer.
In general, think about what you're trying to communicate to the API user by the API prototypes themselves; a clear sense of what the API can do. He doesn't need excessive minutae; he does need to know the core functions which are the entire point of having the API in the first place.
First off, you need to decide which language you are using. Tagging the question with both C and C++ here makes no sense. I am assuming C++.
If you can create a generic function then of course that is preferable (why would you prefer multiple, redundant functions?) The question is; can you? However, you seem to be unaware of templates. We need to see what you have omitted here to tell if you if templates are suitable however:
// Construct a string (command) with those specific params (params->element1, ...)
In the general case, assuming templates are appropriate, all of that turns into:
template <typename T>
unsigned char *Method(CommandTypeEnum command, T *params) {
// more here
}
On a side note, how is buffer declared? Are you returning a pointer to dynamically allocated memory? Prefer RAII type objects and avoid dynamically allocating memory like that if so.
If you are using C++ then I would avoid using void* as you don't really need to. There is nothing wrong with having multiple methods. Note that you don't actually have to rename the function in your first set of examples - you can just overload a function using different parameters so that there is a separate function signature for each type. Ultimately, this kind of question is very subjective and there are a number of ways of doing things. Looking at your functions of the first type, you would perhaps be well served by looking into the use of templated functions
You could create a struct. That's what I use to handle console commands.
typedef int (* pFunPrintf)(const char*,...);
typedef void (CommandClass::*pKeyFunc)(char *,pFunPrintf);
struct KeyCommand
{
const char * cmd;
unsigned char cmdLen;
pKeyFunc pfun;
const char * Note;
long ID;
};
#define CMD_FORMAT(a) a,(sizeof(a)-1)
static KeyCommand Commands[]=
{
{CMD_FORMAT("one"), &CommandClass::CommandOne, "String Parameter",0},
{CMD_FORMAT("two"), &CommandClass::CommandTwo, "String Parameter",1},
{CMD_FORMAT("three"), &CommandClass::CommandThree, "String Parameter",2},
{CMD_FORMAT("four"), &CommandClass::CommandFour, "String Parameter",3},
};
#define AllCommands sizeof(Commands)/sizeof(KeyCommand)
And the Parser function
void CommandClass::ParseCmd( char* Argcommand )
{
unsigned int x;
for ( x=0;x<AllCommands;x++)
{
if(!memcmp(Commands[x].cmd,Argcommand,Commands[x].cmdLen ))
{
(this->*Commands[x].pfun)(&Argcommand[Commands[x].cmdLen],&::printf);
break;
}
}
if(x==AllCommands)
{
// Unknown command
}
}
I use a thread safe printf pPrintf, so ignore it.
I don't really know what you want to do, but in C++ you probably should derive multiple classes from a Formatter Base class like this:
class Formatter
{
virtual void Format(unsigned char* buffer, Command command) const = 0;
};
class YourClass
{
public:
void Method(Command command, const Formatter& formatter)
{
formatter.Format(buffer, command);
}
private:
unsigned char* buffer_;
};
int main()
{
//
Params1Formatter formatter(/*...*/);
YourClass yourObject;
yourObject.Method(CommandA, formatter);
// ...
}
This removes the resposibility to handle all that params stuff from your class and makes it closed for changes. If there will be new commands or parameters during further development you don't have to modifiy (and eventually break) existing code but add new classes that implement the new stuff.
While not full answer this should guide you in correct direction: ONE FUNCTION ONE RESPONSIBILITY. Prefer the code where it is responsible for one thing only and does it well. The code whith huge switch statement (which is not bad by itself) where you need cast void * to some other type is a smell.
By the way I hope you do realise that according to standard you can only cast from void * to <type> * only when the original cast was exactly from <type> * to void *.
could someone please tell me what I need to do in order to create an array of objects in a function (other than in the main function).
I will try to explain by making up some sort of example...
Let's say I have a program named TimeScheduler.cpp that implements the class Schedule.h
(and I have the implementation in a separate file Schedule.cpp where we define the methods).
In the declaration file we have declared two constructors
Schedule(); //the default
and
Schedule(int, int, int);//accepts three arguments
to get to the point--let's say in the main program file TimeScheduler.cpp we created our own functions in this program apart from the functions inherited from the class Schedule. so we have our prototypes listed at the top.
/*prototypes*/
void makeSomeTime();
etc.....
we have
main(){
//etc etc...
}
we then define these program functions
void makeSomeTime(){
//process
}
let's say that inside the function makeSomeTime(), we would like to create an array of Schedule objects like this
Schedule ob[]={
summer(5,14, 49),
fall(9,25,50)
};
what do I have to do to the function makeSomeTime() in order for it to allow me to create this array of objects.
The reason I ask is currently i'm having difficulty with my own program in that it WILL allow me to create this array of objects in main()....but NOT in a function like I just gave an example of. The strange thing is it will allow me to create a dynamic array of objects in the function..... like
Schedule *ob = new Schedule[n+1];
ob[2]= Schedule(x,y,z);
Why would it let me assign to a non-dynamic array in main(), but not let me do that in the function?
This is not correct:
Schedule ob[]={
summer(5,14, 49),
fall(9,25,50)
};
You appear to be trying to introduce 3 new names:
ob, which is an array of Scedules
summer, which is a Schedule
fall, which is a Schedule
You can't introduce summer and fall as new names like that. Perhaps this was just a typo, and you meant:
Schedule ob[]={
Schedule(5,14, 49),
Schedule(9,25,50)
};
...which is perfectly fine, and can exist in a function such as:
void make_schedule()
{
Schedule ob[]={
Schedule(5,14, 49),
Schedule(9,25,50)
};
}
But now you have another problem -- your make_schedule function returns void. The Schedule array you created in make_schedule is created and then just thrown away. If you want to return an array from a functtion, the best thing to do is to use a vector, and return that:
std::vector<Schedule> make_schedule()
{
Schedule ob[]={
Schedule(5,14, 49),
Schedule(9,25,50)
};
const size_t num_obs = sizeof(ob)/sizeof(ob[0]);
std::vector<Schedule> ret;
std::copy( &ob[0], &ob[num_obs], std::back_inserter(ret));
return ret;
}
A poorer alternative is to use dynamic allocation to allocate your array, and return a pointer to the first element. In this case, when using new [] it's important to note that you can only use the default constructor.
I decided that instead of using a vector, I could use an unordered_map. I didn't realize that when you 'name' an object in c++, you aren't really giving it a name...it is simply used as a sort of temporary reference. if you want to use names you are better off using a name as a sort of key value in a set. like:
string foodname;
foodname = "cake";
[foodname, 10.95]
foodname = "bread";
[foodname, 5.75]
I found help with unordered_map on http://msdn.microsoft.com/en-us/library/bb981993.aspx
I am making a command prompt in C++. I would like a user to enter a line such as "say something". This will then be split up so that "say" would be the command name and "something" would be a parameter. So far, so good - this is already working.
I would then like to use the name of the command to call the appropriate method. I could use some kind of look-up table but is there a better method?
probably you need something like map of command keywords and function or method pointers
#include <string>
#include <map>
class CmdHandler // our handler class
{
public:
void Handler(const std::string &arg){}//our handler method
};
typedef void (CmdHandler::*MethodPtr)(const std::string &); // make typedef to easily deal with the type of the member-function pointer
std::map<std::string, MethodPtr> my_handlers; // make our method lookup table
int _tmain(int argc, _TCHAR* argv[])
{
CmdHandler handler;
//add a real member-function pointer for the "say" command
my_handlers.insert(std::make_pair("say", &CmdHandler::Handler));
//look for the handler of command "say" and call it instantly
(handler.*my_handlers["say"])("something");
return 0;
}
C++ doesn't support any kind of reflection: some sort of table mapping names to function objects is the best approach I'm aware of.
A look up table is the usual method. Usually, a std::map...and if you're using boost, you might want to look at boost::function and boost::bind.
Also note that you might find the compiler macro __FUNCTION__ (which expands to the undecorated name of the current function at compile time, and is often used in error messages - you might have to strip class names from member function names) useful in command functions, in order register functions in your map so that you can avoid misspellings and extra typing.
(Note that BOOST_CURRENT_FUNCTION might be a more portable macro.)