Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ SMAUG ➜ SMAUG coding ➜ Dynamically-Called Functions?

Dynamically-Called Functions?

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1 2  

Posted by Kris   USA  (198 posts)  Bio
Date Tue 31 Dec 2002 08:12 AM (UTC)
Message
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?
Top

Posted by Orange   United Kingdom  (25 posts)  Bio
Date Reply #1 on Tue 31 Dec 2002 12:46 PM (UTC)
Message
This should be enough to get you started...


#include <dlfcn.h>
#include <stdio.h>

void do_hello(const char *w) {
  printf("Hello %s.\n", w);
}

int main() {
  void *v = dlopen(0, RTLD_NOW);
  void (*fn)(const char *);
  if (!v)
    return 1;

  fn = dlsym(v, "do_hello");
  if (fn) {
    fn("world");
  }
  dlclose(v);
  return 0;
}


Needs linking with -ldl and -rdynamic under gcc.
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #2 on Tue 31 Dec 2002 07:11 PM (UTC)
Message
Would the -rdynamic and -|d| go under C_FLAGS or L_FLAGS in Makefile? Hehe I've never been too snappy with makefiles....
Top

Posted by Orange   United Kingdom  (25 posts)  Bio
Date Reply #3 on Tue 31 Dec 2002 08:17 PM (UTC)

Amended on Tue 31 Dec 2002 08:19 PM (UTC) by Orange

Message
I said link, so L_FLAGS. Btw, note it is "-ldl" (with els), not -|d| as you wrote. (which has pipes)
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #4 on Tue 31 Dec 2002 08:22 PM (UTC)
Message
I got compile errors when I tried to add -|d| and -rdynamic to either L_FLAGS or C_FLAGS.

gcc: -E required when input is from standard input
d: not found
-rdynamic: not found


Did I misinterpret what you were saying, or perhaps I missed something? Like I said, I'm not too good with makefiles hehe.
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #5 on Tue 31 Dec 2002 08:28 PM (UTC)
Message
Ok I just tried it with "ldl" instead of pipes, and put it in L_FLAGS. Now I get this error:

gcc: unrecognized option '-rdynamic'
/usr/lib/gcc-lib/i686-pc-cygwin/2.95.3-5/../../../../i686-pc-cygwin/bin/ld: cannot find -ldl
collect2: ld returned 1 exit status


Looks like the compiler is unfamiliar with those flags.
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #6 on Tue 31 Dec 2002 08:54 PM (UTC)
Message
My version of gcc seems to support -dynamic, rather than -rdynamic.

Try gcc --version to see what version you have.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #7 on Tue 31 Dec 2002 08:56 PM (UTC)
Message
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.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #8 on Tue 31 Dec 2002 09:03 PM (UTC)
Message
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)?
Top

Posted by Orange   United Kingdom  (25 posts)  Bio
Date Reply #9 on Tue 31 Dec 2002 09:14 PM (UTC)
Message
It may be that the dl* functions are in cygwin's libc directly, so just kill the -ldl.
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #10 on Tue 31 Dec 2002 10:44 PM (UTC)
Message
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.
Top

Posted by Orange   United Kingdom  (25 posts)  Bio
Date Reply #11 on Tue 31 Dec 2002 11:47 PM (UTC)
Message
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.
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #12 on Wed 01 Jan 2003 02:04 AM (UTC)
Message
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?

Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #13 on Wed 01 Jan 2003 07:51 AM (UTC)
Message
Quote:

(since I have no idea what -ldl even is hehe)?


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.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Kris   USA  (198 posts)  Bio
Date Reply #14 on Wed 01 Jan 2003 08:46 AM (UTC)
Message
Yah there's no libdl.a in there. That in mind, is there ANYTHING else I can do? The dynamic function thing is rather crucial to what I'm trying to do.
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


80,872 views.

This is page 1, subject is 2 pages long: 1 2  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.