472,988 Members | 2,643 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,988 software developers and data experts.

How to call a function just using a string?

Hi All!
I have a question that how to call a function just using a string.
For example
There is a .cpp file named a.cpp.There are some functions::fun1()
fun2() fun3().
I have another fucntion void funcall( char *pch). if I pass a
argument char* p1="fun1" .How do I call the function fun1() using that
string "fun1"that I pass.
Dec 4 '07 #1
11 2811
dolphin wrote:
I have a question that how to call a function just using a string.
For example
There is a .cpp file named a.cpp.There are some functions::fun1()
fun2() fun3().
I have another fucntion void funcall( char *pch). if I pass a
argument char* p1="fun1" .How do I call the function fun1() using that
string "fun1"that I pass.
I'm not aware of any way to do this in portable C++.

Some "solutions":

* Have funcall add some code to a.cpp that allows to select a function
and compile and execute the file,
* dynamically load the file, runtime-binding the desired function(s) and
invoke them,
* make funcall an interface to a C++ interpreter, and run it on a.cpp,
calling the desired function,
* make funcall send a mail to your annoyed cow-orker, instructing him to
edit, compile and run the file so that the desired function will be
executed.
Dec 4 '07 #2
On Dec 4, 12:37 pm, dolphin <jdxyw2...@gmail.comwrote:
Hi All!
I have a question that how to call a function just using a string.
For example
There is a .cpp file named a.cpp.There are some functions::fun1()
fun2() fun3().
I have another fucntion void funcall( char *pch). if I pass a
argument char* p1="fun1" .How do I call the function fun1() using that
string "fun1"that I pass.
#include <map>
#include <string>

typedef std::map<std::string,void(*)(void)FuncMapTypeBase;

struct FuncMapType :
FuncMapTypeBase
{
FuncMapType(){
(*this)["fun1"]=&fun1;
(*this)["fun2"]=&fun2;
(*this)["fun3"]=&fun3;
}
};

const FuncMapType &funxns(){
static FuncMapType funcs;
return funcs;
};

void funcall(const std::string& str){
(*(funcxns()[str]))();
};

regards,
FM
Dec 4 '07 #3
On Dec 4, 2:37 pm, dolphin <jdxyw2...@gmail.comwrote:
Hi All!
I have a question that how to call a function just using a string.
For example
There is a .cpp file named a.cpp.There are some functions::fun1()
fun2() fun3().
I have another fucntion void funcall( char *pch). if I pass a
argument char* p1="fun1" .How do I call the function fun1() using that
string "fun1"that I pass.
Does not do exactly what you are asking for but something similar -
dlopen, dlsym and dlclose. This is linux/unix specific. For windows -
you have LoadLibrary and GetProcAddress. For other platforms, you
would need to find alternatives.
Dec 4 '07 #4
On Dec 4, 10:59 pm, Abhishek Padmanabh <abhishek.padman...@gmail.com>
wrote:
On Dec 4, 2:37 pm, dolphin <jdxyw2...@gmail.comwrote:
Hi All!
I have a question that how to call a function just using a string.
For example
There is a .cpp file named a.cpp.There are some functions::fun1()
fun2() fun3().
I have another fucntion void funcall( char *pch). if I pass a
argument char* p1="fun1" .How do I call the function fun1() using that
string "fun1"that I pass.

Does not do exactly what you are asking for but something similar -
dlopen, dlsym and dlclose. This is linux/unix specific. For windows -
you have LoadLibrary and GetProcAddress. For other platforms, you
would need to find alternatives.
These functions are defined by myself in one .cpp file.Can it be
called by LoadLibrary?
Dec 5 '07 #5
On Dec 5, 9:45 am, dolphin <jdxyw2...@gmail.comwrote:
On Dec 4, 10:59 pm, Abhishek Padmanabh <abhishek.padman...@gmail.com>
wrote:
On Dec 4, 2:37 pm, dolphin <jdxyw2...@gmail.comwrote:
Hi All!
I have a question that how to call a function just using a string.
For example
There is a .cpp file named a.cpp.There are some functions::fun1()
fun2() fun3().
I have another fucntion void funcall( char *pch). if I pass a
argument char* p1="fun1" .How do I call the function fun1() using that
string "fun1"that I pass.
Does not do exactly what you are asking for but something similar -
dlopen, dlsym and dlclose. This is linux/unix specific. For windows -
you have LoadLibrary and GetProcAddress. For other platforms, you
would need to find alternatives.

These functions are defined by myself in one .cpp file.Can it be
called by LoadLibrary?
It depends on the linkage if you use ordinary (static) linkage the
answer is No.
But if you make some changes to the project specifications or compiler
switches then Yes.

I guess you do not want to use dynamic link libraries;If so please
take a look at my former post.

regards,
FM.
Dec 5 '07 #6
Dear Terminator,
I find your code to be quite enthralling, however, I do not understand
the bulk of it. =(

Could you comment out your lines so that I understand what is going
on.

Thanks a lot =)

Dec 6 '07 #7
On 2007-12-04 06:04:46 -0500, terminator <fa***********@gmail.comsaid:
On Dec 4, 12:37 pm, dolphin <jdxyw2...@gmail.comwrote:
>Hi All!
I have a question that how to call a function just using a string.
For example
There is a .cpp file named a.cpp.There are some functions::fun1()
fun2() fun3().
I have another fucntion void funcall( char *pch). if I pass a
argument char* p1="fun1" .How do I call the function fun1() using that
string "fun1"that I pass.

#include <map>
#include <string>

typedef std::map<std::string,void(*)(void)FuncMapTypeBase;

struct FuncMapType :
FuncMapTypeBase
{
FuncMapType(){
(*this)["fun1"]=&fun1;
(*this)["fun2"]=&fun2;
(*this)["fun3"]=&fun3;
}
};

const FuncMapType &funxns(){
static FuncMapType funcs;
Will this be allowed here? FuncMapType has private constructor.

Otherwise, your code is a nice demonstration of how to do object
aggregation and singleton.
return funcs;
};

void funcall(const std::string& str){
(*(funcxns()[str]))();
};

regards,
FM

--

-kira

Dec 6 '07 #8
On Dec 5, 6:21 pm, terminator <farid.mehr...@gmail.comwrote:
On Dec 5, 9:45 am, dolphin <jdxyw2...@gmail.comwrote:
On Dec 4, 10:59 pm, Abhishek Padmanabh
<abhishek.padman...@gmail.comwrote:
On Dec 4, 2:37 pm, dolphin <jdxyw2...@gmail.comwrote:
I have a question that how to call a function just using a string.
For example
There is a .cpp file named a.cpp.There are some functions::fun1()
fun2() fun3().
I have another fucntion void funcall( char *pch). if I pass a
argument char* p1="fun1" .How do I call the function fun1() using that
string "fun1"that I pass.
Does not do exactly what you are asking for but something similar -
dlopen, dlsym and dlclose. This is linux/unix specific. For windows -
you have LoadLibrary and GetProcAddress. For other platforms, you
would need to find alternatives.
These functions are defined by myself in one .cpp file.Can it be
called by LoadLibrary?
It depends on the linkage if you use ordinary (static) linkage the
answer is No.
I'm not sure I understand. If he links it statically, then he
doesn't need to use LoadLibrary (or dlopen).

I think that the advantage here in using LoadLibrary/dlopen is
that he can add additional functions later, without having to
recompile/relink the main application; in fact, without even
having to stop the main application.

I've done this in one case, albeit with object types derived
from a common base class, not with pure functions. (But of
course, that could be a trivial wrapper for the pure function.)
Basically, the main application contained an std::map<
std::string, Factory* >, where Factory was an abstract base
class with a virtual function which was called to create the
object. The constructor of Factory (called from the derived
class, of course) took a string with the name of the type it
constructs; it knew about the map, and enroled the instance in
the map. This base class and the map was then statically mapped
into the main application. For the derived classes, I
established a naming convention, associating the string with the
name of the corresponding dynamicly loaded file. That file
contained a static instance of the derived factory, so that when
loaded, the constructor would be called, and the factory
register itself with the map. When I wanted an instance of the
class from a string, I looked up the factory in the map; if I
didn't find it, I constructed the file name, tried to load it,
and then tried the map again.

Under Solaris, the only special action necessary was to link
with -ldl. Under Linux, I also needed some special options when
linking the main application, so that symbols in it (e.g. the
constructor of the base class) would be available to the
dynamically linked object. I've not yet had time to port it to
Windows, but from what I understand: 1) I'll need to do
something special to make the constructor for the base class
visible in the DLL's (note that this is the only symbol needed
to establish the link between the objects), and 2) I may have to
move the constructor of the Base class out into a DLL of its own
(presumably with the map, and everything else which uses it),
since I seem to recall having heard that Windows never makes
symbols in the main application available to DLL's (but I really
have no experience here to be sure).

If you really want to get fancy, you can even upgrade functions
dynamically, without stopping the application. Add code in the
destructor of the base class which deenroles the object from the
map, and a (statically linked) command to unload the DLL, and
all you have to do is unload the DLL, replace the file which
contains it with a new one, and the next time someone tries to
use the command, the new one is loaded.
But if you make some changes to the project specifications or
compiler switches then Yes.
I guess you do not want to use dynamic link libraries;If so
please take a look at my former post.
If he's statically linking, the simplest solution is to use a
static table. Something like:

struct MapElement
{
char const* name ;
void (* func)() ;
} ;

MapElement const table[] =
{
{ "do", &do },
{ "re", &re },
{ "mi", &mi },
// ...
} ;

A simple linear search (with std::find_if) will then take care
of the lookup. (I use a similar construct so often that I have
a template for MapElement, which also defined the corresponding
predicate type for std::find_if. Along with the begin and end
functions which return the "iterators" of a C style array, all I
have to write is something like:

typedef StaticMap< void (*)() >
Map ;
Map const myMap[] =
{
{ "do", &do },
{ "re", &re },
{ "mi", &mi },
// ...
} ;

and then:

Map const* elem
= std::find_if( begin( myMap ), end( myMap ),
Map::Matcher( functionName ) ) ;
if ( elem == end( myMap ) ) {
// Error: function not known...
} else {
(*elem->value)() ;
}

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 6 '07 #9
On Dec 6, 6:59 pm, James Kanze <james.ka...@gmail.comwrote:
On Dec 5, 6:21 pm, terminator <farid.mehr...@gmail.comwrote:


On Dec 5, 9:45 am, dolphin <jdxyw2...@gmail.comwrote:
On Dec 4, 10:59 pm, Abhishek Padmanabh
<abhishek.padman...@gmail.comwrote:
On Dec 4, 2:37 pm, dolphin <jdxyw2...@gmail.comwrote:
I have a question that how to call a function just using a string.
For example
There is a .cpp file named a.cpp.There are some functions::fun1()
fun2() fun3().
I have another fucntion void funcall( char *pch). if I pass a
argument char* p1="fun1" .How do I call the function fun1() using that
string "fun1"that I pass.
Does not do exactly what you are asking for but something similar -
dlopen, dlsym and dlclose. This is linux/unix specific. For windows -
you have LoadLibrary and GetProcAddress. For other platforms, you
would need to find alternatives.
These functions are defined by myself in one .cpp file.Can it be
called by LoadLibrary?
It depends on the linkage if you use ordinary (static) linkage the
answer is No.

I'm not sure I understand. If he links it statically, then he
doesn't need to use LoadLibrary (or dlopen).

I think that the advantage here in using LoadLibrary/dlopen is
that he can add additional functions later, without having to
recompile/relink the main application; in fact, without even
having to stop the main application.

I've done this in one case, albeit with object types derived
from a common base class, not with pure functions. (But of
course, that could be a trivial wrapper for the pure function.)
Basically, the main application contained an std::map<
std::string, Factory* >, where Factory was an abstract base
class with a virtual function which was called to create the
object. The constructor of Factory (called from the derived
class, of course) took a string with the name of the type it
constructs; it knew about the map, and enroled the instance in
the map. This base class and the map was then statically mapped
into the main application. For the derived classes, I
established a naming convention, associating the string with the
name of the corresponding dynamicly loaded file. That file
contained a static instance of the derived factory, so that when
loaded, the constructor would be called, and the factory
register itself with the map. When I wanted an instance of the
class from a string, I looked up the factory in the map; if I
didn't find it, I constructed the file name, tried to load it,
and then tried the map again.

Under Solaris, the only special action necessary was to link
with -ldl. Under Linux, I also needed some special options when
linking the main application, so that symbols in it (e.g. the
constructor of the base class) would be available to the
dynamically linked object. I've not yet had time to port it to
Windows, but from what I understand: 1) I'll need to do
something special to make the constructor for the base class
visible in the DLL's (note that this is the only symbol needed
to establish the link between the objects), and 2) I may have to
move the constructor of the Base class out into a DLL of its own
(presumably with the map, and everything else which uses it),
since I seem to recall having heard that Windows never makes
symbols in the main application available to DLL's (but I really
have no experience here to be sure).

If you really want to get fancy, you can even upgrade functions
dynamically, without stopping the application. Add code in the
destructor of the base class which deenroles the object from the
map, and a (statically linked) command to unload the DLL, and
all you have to do is unload the DLL, replace the file which
contains it with a new one, and the next time someone tries to
use the command, the new one is loaded.
But if you make some changes to the project specifications or
compiler switches then Yes.
I guess you do not want to use dynamic link libraries;If so
please take a look at my former post.

If he's statically linking, the simplest solution is to use a
static table. Something like:

struct MapElement
{
char const* name ;
void (* func)() ;
} ;

MapElement const table[] =
{
{ "do", &do },
{ "re", &re },
{ "mi", &mi },
// ...
} ;

A simple linear search (with std::find_if) will then take care
of the lookup. (I use a similar construct so often that I have
a template for MapElement, which also defined the corresponding
predicate type for std::find_if. Along with the begin and end
functions which return the "iterators" of a C style array, all I
have to write is something like:

typedef StaticMap< void (*)() >
Map ;
Map const myMap[] =
{
{ "do", &do },
{ "re", &re },
{ "mi", &mi },
// ...
} ;

and then:

Map const* elem
= std::find_if( begin( myMap ), end( myMap ),
Map::Matcher( functionName ) ) ;
if ( elem == end( myMap ) ) {
// Error: function not known...
} else {
(*elem->value)() ;
}
This is of course more efficient but needs more code typing
especifically if readability is trigered.
I just tried to show the posibility via the first and simplest
portable way to write it.

regards,
FM.
Dec 6 '07 #10
On Dec 6, 8:37 am, Kira Yamato <kira...@earthlink.netwrote:
On 2007-12-04 06:04:46 -0500, terminator <farid.mehr...@gmail.comsaid:


On Dec 4, 12:37 pm, dolphin <jdxyw2...@gmail.comwrote:
Hi All!
I have a question that how to call a function just using a string.
For example
There is a .cpp file named a.cpp.There are some functions::fun1()
fun2() fun3().
I have another fucntion void funcall( char *pch). if I pass a
argument char* p1="fun1" .How do I call the function fun1() using that
string "fun1"that I pass.
#include <map>
#include <string>
typedef std::map<std::string,void(*)(void)FuncMapTypeBase;
struct FuncMapType :
FuncMapTypeBase
{
FuncMapType(){
(*this)["fun1"]=&fun1;
(*this)["fun2"]=&fun2;
(*this)["fun3"]=&fun3;
}
};
const FuncMapType &funxns(){
static FuncMapType funcs;

Will this be allowed here? FuncMapType has private constructor.

Otherwise, your code is a nice demonstration of how to do object
aggregation and singleton.
return funcs;
};
void funcall(const std::string& str){
(*(funcxns()[str]))();
};
had I used the 'class' keyword you would have been ahead by one
point ,But it is a 'struct'( because I am lazy in typing) and has
default public access.

regards,
FM.
Dec 6 '07 #11
On 2007-12-06 12:44:28 -0500, terminator <fa***********@gmail.comsaid:
On Dec 6, 8:37 am, Kira Yamato <kira...@earthlink.netwrote:
>On 2007-12-04 06:04:46 -0500, terminator <farid.mehr...@gmail.comsaid:


>>On Dec 4, 12:37 pm, dolphin <jdxyw2...@gmail.comwrote:
Hi All!
I have a question that how to call a function just using a string.
For example
There is a .cpp file named a.cpp.There are some functions::fun1()
fun2() fun3().
I have another fucntion void funcall( char *pch). if I pass a
argument char* p1="fun1" .How do I call the function fun1() using that
string "fun1"that I pass.
>>#include <map>
#include <string>
>>typedef std::map<std::string,void(*)(void)FuncMapTypeBase;
>>struct FuncMapType :
FuncMapTypeBase
{
FuncMapType(){
(*this)["fun1"]=&fun1;
(*this)["fun2"]=&fun2;
(*this)["fun3"]=&fun3;
}
};
>>const FuncMapType &funxns(){
static FuncMapType funcs;

Will this be allowed here? FuncMapType has private constructor.

Otherwise, your code is a nice demonstration of how to do object
aggregation and singleton.
>>return funcs;
};
>>void funcall(const std::string& str){
(*(funcxns()[str]))();
};

had I used the 'class' keyword you would have been ahead by one
point ,But it is a 'struct'( because I am lazy in typing) and has
default public access.
Ah. Silly me. Very nice collection of tricks you used in such a small
sample code.

--

-kira

Dec 6 '07 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Sue | last post by:
After finishing up my first quarter JavaScript on 12/12/03, I decided to improve character checking on my project. In my project I only had to do very basic validation. Therefore, I only had one...
1
by: cheezebeetle | last post by:
ok, so I am having problems passing in an ASPX function into the Javascript in the codebehind page. I am simply using a confirm call which when they press "OK" they call this ASPX function, when...
39
by: Randell D. | last post by:
Folks, I'm sure this can be done legally, and not thru tricks of the trade - I hope someone can help. I'm writing a 'tool' (a function) which can be used generically in any of my projects. ...
5
by: Rob | last post by:
Help me, I'm just beginning with programming in Access 2000. I've tried the http://www.mvps.org/access/api/api0001.htm but it won't work in Access. What am i doing wrong. I don't have...
3
by: John Smith | last post by:
I wrote some code in C in a dll which I would like to call from C#. However I'm stuck because of the strongly typed behavior of C# which makes limitations. Here are the prototypes for two...
8
by: Berhack | last post by:
I am not too familiar with C# interop so please help me out. I need to call the following C function (in a DLL): // this creates an array of strings // LPTSTR is just char * void C_Func(LPTSTR...
10
by: bienwell | last post by:
Hi, I have a question about file included in ASP.NET. I have a file that includes all the Sub functions (e.g FileFunct.vb). One of the functions in this file is : Sub TestFunct(ByVal...
5
by: Kurt Van Campenhout | last post by:
Hi, I am trying to get/set Terminal server information in the active directory on a windows 2000 domain. Since the ADSI calls for TS don't work until W2K3, I need to do it myself. I'm fairly...
5
by: Lee | last post by:
(I also posted this query in Microsoft.Public.DotNet.Framework yesterday, but since I have received no responses, I am posting it here too.) Using Windows XP with all updates applied and Visual...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM) Please note that the UK and Europe revert to winter time on...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
4
by: GKJR | last post by:
Does anyone have a recommendation to build a standalone application to replace an Access database? I have my bookkeeping software I developed in Access that I would like to make available to other...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.