This is hard to explain, so bear with me. I want to be able to call a function name dynamically. Bleh I think an example would be best....
Let's say we have a string variable, char *testcommand. Let's also say that, at some point, testcommand = "send_to_char"
Would there be a way for me to make a function call using testcommand? In this case, it would be a call to the send_to_char function.
Being able to do this would have some real advantages, such as potentially eliminating the need for the do_funtions listings in tables.c, although that's not what I'm working on.
I know this is done rather easily in java, but C is a totally different animal. Any thoughts on that Nick?
I'm not sure if you can eliminate the function tables. The method described might map "a" to the address fo function "a", but not do the reverse map. That is, given an address find the function name. I think the code needs to do that when writing an area.
Yah I'm not trying to eliminate the function tables; that was just an example I used to help illustrate what I'm trying to do with the dynamic functions.
Here's my version of gcc:
2.95.3-5
Remember it's cygwin, not linux (dunno if that matters). I changed the '-rdynamic' to '-dynamic' and it worked, but the '-ldl' is still giving me the same error. Any idea what I should use in place of that (since I have no idea what -ldl even is hehe)?
Ok it compiles fine now, but the code example you gave me has absolutely no effect whatsoever. I put it in interp.c, and used it as follows:
/*
* Look for command in skill and socials table.
*/
if ( !found )
{
/* Dynamic Funtion Call Test */
void *v = dlopen(0, RTLD_NOW);
void (*fn)(const char *);
...And then after it checks to see if the command is a valid exit....
else if ( v )
{
fn = dlsym(v, "log_string" );
if (fn) {
fn("This is a test");
}
}
dlclose(v);
send_to_char( "Huh?\n\r", ch );
Basically, if I type nonsense (like "woejhrqwe" or something), it should make the function call log_string( "This is a test" ); and then send "Huh?" to me. However, the log_string is not happening.
Is dlopen() failing, or is dlsym() failing? On some platforms you have to prepend "_" to the 2nd parm of dlsym. Never done it before myself on Windows, but I know it's possible.
I have no idea which one is failing. I've never done anything with either dload or dslym before, so I wouldn't know. I just know it's not having any effect; no errors, bugs, or anything.
With the "_" thing, you mean change fn = dlsym(v, "log_string" );
to
fn = dlsym(v, _"log_string" ); or something?
The -l command line option asks gcc to use a library, which has "lib" in front and ".a" at the back. In other words, in this case, it would be a file libdl.a that is being linked into your executable. If there is no such file it won't work.
Certainly. You can start debugging and find out which function call is returning NULL. If that's beyond you at the moment then function pointers probably are too.
log_string is a void function; it's supposed to return NULL. As for the dlopen and such, I have no idea what those are, let alone how to debug them.
It is essential that I get this dynamic function call thing to work. Although I have no experience with that, I can figure it out with a little help hehe. I just want it to work! =)
Do you want to be able to call arbitrary functions, or from a known list? Do they need to share all the address space of the main server? Maybe you can spawn off another process and pipe things to it.
Ok remember that Secondary Command Processor idea I was spinning around? Ya know, a seperate process; stripped-down version of the mud that shares a bit of memory with the primary mud server. I made a post about it back in October I think.
Two things would have to exist for that to really work (I would distribute it as a snippet if it proved viable). First of all would be the shared memory. That's something I'm still researching, but it looks like it can be done under windows. The second would be the ability to call functions in the other process (i.e. call "send_to_char" from the secondary command processor). In order to do that, the process can send a string to the other process via the shared structure, which would then be used to call the function name equal to that string.
So yah, to make it fully flexible and useful, it would have to be dynamic (or 'arbitrary' as you put it). I.e. I would have to be able to call any function that exists on the other mud, without having to maintain an extensive (and cumbersome) list.
Where should I go from here in order to get the dynamic function thingie to work?
What you describe sounds looks like it would require pretty well writing a fullscale mud from scratch simply to handle the function calls from your original world. The *cough* easy *cough* way would be to convert everything to a database and have the sub process handle calls thru the database but even that is going obscenely difficult to accomplish. I rather suspect any speed you gain in doing this will be neglegable under all but the most extreme of circumstances unless yer trying to run your mud on a 486/33SX with 8MB of RAM. Any computer with a pentium processor or better and a decent amount of RAM(128 minimal) should be able to handle the demands of a mud pretty well seamlessly.
I'm not doing this for speed. One benefit, for example, is the ability to add/change code in the mud without having to shut it down. I'd just have to have the secondary command processor go offline for a few seconds while it recompiles.
It won't require the creation of a new codebase either. I'll add a function that does all the handling/communication with the SCP, which will be called in game_loop of comm.c. That should be easy enough to work through.
Again, the only thing standing in my way is this dynamic function thing! I need to get past this brick wall before I can do anything else.
How can I get this dynamic function call stuff to work under cygwin????
You said at one point you have the ability to copyover, why do you need to shutdown to update code? As for making such a project work under Cygwyn, everything I can find seems to indicate it won't work under Cygwin. MSVC should be able to handle it but Cygwin doesnt seem to have the capability to handle the necessary call functions to communicate between the seperate processes.
Again I think you could do this sort-of by piping requests to a separate process, the separate process could be restarted. Sounds a big job, and I don't have Cygwin with me right now to try ideas out.
Man I'm having trouble just finding an appropriate search pattern.... Skimming through google, I managed to figure out how to do it in about 3 other programming languages, but not C....
Asked over IMC, but the only people who spoke up were Samson and Orion, neither of whom had a clue.
So my frusterating search continues.... I know there HAS to be a way to accomplish this somehow....
Ever the spin doctor there eh Kris? No, we aren't clueless. It has more to do with the fact that, well, we just don't like you. There. It's been said. Now with that out of the way.... yes, it can be done. You simply weren't willing to do the minimal amount of research needed to uncover your solution. I'm not going to tell you here since you've decided to try and run your smear campaigns again.
To everyone else, apologies for having to vent on him here. I'm sure if you all knew just how much of a pain he's made of himself on IMC over every last little thing, code related or otherwise, you'd understand.