Skip to main content
GameDev.net gamedev.net
🔒 Locked

Calling functions

Started by TiitHns Jan 21, 2008 at 10:52 AM 10 replies 2.2k views
Original Post
TiitHns
TiitHns
Does any one know is this possible. Calling functions like this CallFunction("FunctionName"); This should work without switch cases and if statements. It should acssess some way to function address
http://www.daily-it.com
SiCrane
SiCrane
In what language?
TiitHns
TiitHns
i looked into it and it seems it cant be done with c++ only. Some code parts must be in assembly.
http://www.daily-it.com
rip-off
rip-off
Quote:
Original post by TiitHns
i looked into it and it seems it cant be done with c++ only. Some code parts must be in assembly.


Certainly not. It depends on what you are trying to do though.
Do the functions all share the same signature (arguments and return types)?
Can you build a list of all the callable functions at compile time?

Look into std::map. Also look up function pointers/functors. Or a wrapper thereof such as boost::function.

[Edited by - rip-off on January 21, 2008 11:06:40 AM]
ShaunPeoples
ShaunPeoples
I'd have to agree with rip-off on this one. This is exactly the way I implemented a simple scheme for calling functions from an early scripting language try. Look at:

http://www.function-pointer.org/

For a great overview of function pointers.
Antheus
Antheus
typedef void (*fp)();std::map< std::string, fp> functions;


Or something similar.
Thunder Sky
Thunder Sky
I've been wondering the same thing for quite a while

As far as I know, its not possible to build a list of defined functions automatically. You'd have to use some kind of preprocessor macros when defining functions that you'd want to be listed.

I have heard though that some (not all?) versions of .exe files store the accual (decorated) string names of functions in the generated output file. But this might only be debug builds.

Even one more option is to define CallFunction as a macro and "de-string" it's argument so that it is parsed as a linker symbol rather than a string of bytes.

I had a quick look at boost::function but since Im not very familiar with boost and the document was looong I didnt find anything useful.

Would be very interested in how to solv this
Thunder Sky
Thunder Sky
only replied because there wasnt any replies in a while..and while Im writing Im beaten to it by the two of you.. :)

anyway, I think that the solutions you provide doesnt apply to his situation. Both boost:function (or any function pointer/functor) needs the programmer to specify the address it points to with "linker symbols" e.g. a function name. However he is trying to call a function based on the name the programmer gave it. The same applies to std::map. You have to populate it with strings and a corresponding adress to be able to use that pair. And you can only pair two sensible values together at compile time.

I remember now how you can make the output file contain the string name of a function. Use the export keyword (or extern "C" { export ... } to remove decoration). Im not sure if you can call something like GetProcAddress on yourself . I think Half-Life uses something like this when reading npc names from map files and calling the corresponding monsters spawn function using that string. In this situation it was hl.exe that loaded the map and called hl.dll to spawn the monster though.

As before, eager to be tought how this really works
TiitHns
TiitHns
http://www.codersource.net/win32_dlls.html Thunder Sky thanks. I hope this link helps others to who were wondering about that.

Now i have to just wonder how to do same thing with variables. Setvariable("this",100); SetVariable("that","heyhey");
http://www.daily-it.com
rip-off
rip-off
Quote:
Original post by TiitHns
http://www.codersource.net/win32_dlls.html Thunder Sky thanks. I hope this link helps others to who were wondering about that.

Now i have to just wonder how to do same thing with variables. Setvariable("this",100); SetVariable("that","heyhey");


More complicated. However, you haven't told us what you want to do. It would appear that you want something like a scripting language to manipulate your C++ code. You might get better results using a real scripting language like Lua. However, maybe not. This is why it is important to explain what you are trying to do, not just to ask how to go about it.
Thunder Sky
Thunder Sky
Quote:

This is why it is important to explain what you are trying to do, not just to ask how to go about it.

Unless you're asking just to learn :)


The link you posted demonstrates what I mean. It seems to be rather poorly written though:

Firtly, it never explaines what DEMODLL_API is; is't probably defined as
#define DEMODLL_API __declspec(dllexport)

This tells the compiler to save the name as a string, together with the accual address of the function. It's probably saved in some table at the beginning of the outputted file, much like the std::map we talked about earier.


Secondly Im not sure you can use a custom .def file. In my (brief) experience with dlls and gcc you just had to go with the names from the .def generated efter compiling the dll. Defining "explicit exports" might be a MS specific luxury, anyone who wants to clarify that?

When I think about it I believe I have read somewhere that you can call
LoadLibrary("MyExe.exe");

from code inside "MyExe.exe", ie calling LoadLibrary on oneself. I dont think this is 100% supported tho but it should work.

As for doing the same with variables..I think you only have to specify __declspec(dllexport) in front of the variable name to be able to get the address of it (a pointer to it) with GetProcAddress().

Or you could do this. I think this is how most APIs do it, even though I know it isnt exactly what you're looking for.
int MyVar;extern "C" {  //this removes C++ function name decoration              //keep in mind though that C adds              //a _ at the beginning of the function name              //use GetProcAddress("_ModifyMyVar");__declspec(dllexport) void ModifyMyVar(int newvalue) {  MyVar=newvalue;  };}

This, of course, quickly grows inpractical if you have a lot of variables

Thanks for jogging(?) my memory :P hope that helps


EDIT

looking at this it looks like the .def file might not be as MS specific as I thought (even if the info is taken from microsofts page). One thing that surprised me though is this:
Quote:

The dllexport and dllimport storage-class attributes are Microsoft-specific extensions to the C and C++ languages

I have used them with Dev-Cpp (=Mingw=gcc) and it worked. They also mention a __export keyword. I must admit that was what my instincts told me to write in my first reply..but now I cant seem to remember reading about it anywhere before. Its probably easy to look it up on the net..but if anyone has a short, simple explanation of these different terms (and when to use which) it wouldnt hurt.

Also, what the hell is dllimport? How does the compiler/linker know (at compile time) what library the value (address) should be loaded from when we're dealing with Dynamically Linked Libraries? What if we load 2 dlls that both exports a function with that name? If I remember correctly __import can be used with static liked libraries because then we know what we need to know at compile time (and if 2 static linked libraries define the same symbols the liker will generate an error)

/EDIT

/thunder sky

[Edited by - Thunder Sky on January 23, 2008 7:10:11 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.