Function Strings
Function Strings
How can I call a function, given its name as a string?
Any idea's on this?
Any idea's on this?
Only Human
Re:Function Strings
Using dynamic linking functions such as those in posix. Call one of those functions and request the base address, then call that as a function pointer.Neo wrote: How can I call a function, given its name as a string?
Any idea's on this?
Other option, parse your own executable. This is kind of double work.
Re:Function Strings
Can't we use ## operator to concatenate the contents of the variable containg the function name as string and () to call the appropriate function?
Re:Function Strings
Not once you understand the difference between compile-time and run-time. The name is resolved compile-time, you assemble the name during run-time. Unless you call the linker after that (at runtime) you cannot call the function. Dynamic linking in essence is calling the linker at runtime.Guest wrote: Can't we use ## operator to concatenate the contents of the variable containg the function name as string and () to call the appropriate function?
Re:Function Strings
or, you could implement some sort of "internal dynamic linking" by having an associative array of pairs:
(function name as a string) => (function pointer)
then register all functions of interest upon startup and look them up by name later.
that's assuming that the set of functions to be called all have the same, predefined prototype.
if you want to have full flexibility and be able to dynamically call functions with different prototypes, then you would have to implement some sort of a "call compiler" which would work with a dynamic call and a function prototype somehow encoded.
(but then it starts to look a lot like a scripting language...)
that, or use some kind of a universal "variant" datatype and deal with it in the function being called.
(function name as a string) => (function pointer)
then register all functions of interest upon startup and look them up by name later.
that's assuming that the set of functions to be called all have the same, predefined prototype.
if you want to have full flexibility and be able to dynamically call functions with different prototypes, then you would have to implement some sort of a "call compiler" which would work with a dynamic call and a function prototype somehow encoded.
(but then it starts to look a lot like a scripting language...)
that, or use some kind of a universal "variant" datatype and deal with it in the function being called.
Re:Function Strings
For some reason, Java might be a better language to do this in. It allows you to load classes by name, invoke methods by name, etc. if you use the right classes from java.lang.* ...
Re:Function Strings
guys... you're reinventing the wheel
The exact point of dynamic linking is to allow replacement of components, and to allow calling of funcitons that are only known at runtime. Try the dynamic linking library that's distributed with every linux system I know. Loading a class late is a dynamic linker operation. Invoking a method by name is a dynamic linker issue. Even internal dynamic linking is the exact same, but you're reproducing the code already generated by the dynamic linker! Just use the linker the way it's meant to be and don't reinvent the wheel yet another time.
The exact point of dynamic linking is to allow replacement of components, and to allow calling of funcitons that are only known at runtime. Try the dynamic linking library that's distributed with every linux system I know. Loading a class late is a dynamic linker operation. Invoking a method by name is a dynamic linker issue. Even internal dynamic linking is the exact same, but you're reproducing the code already generated by the dynamic linker! Just use the linker the way it's meant to be and don't reinvent the wheel yet another time.
Re:Function Strings
there, you said it yourself - linux! what about those programming for windows? (which is only used by the negligible, overwhelming majority of users, true, so it can be easily dismissed, but still..)Try the dynamic linking library that's distributed with every linux system I know.
so that's not "the" linker, but "a" linker. one of at least 2 (if you look at windows and linux). they do mostly the same thing, the difference is in the details, but still that difference has to be dealt with.
so it would be more like:
"Just use a linker the way it's meant to be and don't reinvent the wheel yet another time. Instead either lock yourself to a particular platform, or deal with a fair amount of conditional compilation, or some other trickery."
besides, creating a separate dynamic executable for the sheer purpose of being able to call a few functions.. no, thanks, i'll just take my trusty dictionary and stick some pointers in there (which by the way is both easier and more flexible)
besides, reinventing some wheels is sometimes a good exercise.
and some wheels are rusty, badly broken and in need of serious reinventing (not to point the finger at windows or linux).
for another reason, i made my own, all-terrain wheels that can run on linux and windows alike (and of course my future OS of the future), therefore my programs compile with no or trivial modifications. that's programs that use files, sockets, threads and user interface.
stop reinventing the wheel? no thanks, i'll keep reinventing.
Re:Function Strings
I guess in this case you may want to write a wrapper for Linux and Windows linker instead of parsing all that stuff yourself.
Re:Function Strings
resolving the problem between two complex libraries by making your own isn't helping the general problem, the dynamic linking function has got to go somewhere. Both platforms DO dynamic linking, for your shared libraries (.so and .dll alike), and they do have those functions. My idea would be to wrap them and forget their OS details.
Not to reinvent the wheel. I'm more than happy to support both wheels, if it means I don't have to drive on the sidewalk (your wheels take up some more space, next to those already present).
Not to reinvent the wheel. I'm more than happy to support both wheels, if it means I don't have to drive on the sidewalk (your wheels take up some more space, next to those already present).
Re:Function Strings
and i will too. it will contain a wrapper, but it will be more than a wrapper, but a higher-level abstraction that does the job, not just parts of it.you may want to write a wrapper for Linux and Windows linker
that's exactly my point - it doesn't have to. if all you have is a hammer.. standard dynamic linking isn't a solution to all of life's problems, you can't just use it for everything that has the word "dynamic" in it. can you "link" functions that are already in your executable, or are you forced to move them out into a dynamic library? my point is, it's neither a full-featured linking nor dynamic enough. in short, inflexible.the dynamic linking function has got to go somewhere
p.s. it does have its uses, i agree, and that is exactly right.
Re:Function Strings
Use a language like Scheme that supports first-class functions directly
[tt]
(eval (list (string->symbol "square") 2))
> 4
[/tt]
[tt]
(eval (list (string->symbol "square") 2))
> 4
[/tt]
Re:Function Strings
That could be though as cheating..Schol-R-LEA wrote: Use a language like Scheme that supports first-class functions directly
[tt]
(eval (list (string->symbol "square") 2))
> 4
[/tt]
As soon as you use eval in your code, your whole interpreter/compiler needs to be included with the final binary, so you could just as well call GCC as a slave process =)
Re:Function Strings
True, in compiled code (eval) has some serious overhead. Whether it's cheating or not depends on whether the evaluator is part of the language itself (it is in Scheme, but not in C).
Now, what's interesting is that I originally thought that I could just run it as
[tt]((string->symbol "sqrt") 2)[/tt]
However, that doesn't work. AFAICT, the reason for this is that, while it passes the name of the function, it does not evaluate to the function itself. Thus, I could have written it instead as
[tt]((eval (string->symbol "sqrt")) 2)[/tt]
But that still have the (eval) call in it.
Now, what's interesting is that I originally thought that I could just run it as
[tt]((string->symbol "sqrt") 2)[/tt]
However, that doesn't work. AFAICT, the reason for this is that, while it passes the name of the function, it does not evaluate to the function itself. Thus, I could have written it instead as
[tt]((eval (string->symbol "sqrt")) 2)[/tt]
But that still have the (eval) call in it.