Suppose I have a dll with 2 functions.name of dll="dll1"
f1(int a, int b, int c);
f2(int a);
My program would take the function name ,the dll name and a "list" of parameters as input.
how would i call the appropriate function with its appropriate parameters.
i.e,
if input is
dll1
f1
list(5,8,9)
this would require me to call f1 with 3 parameters
if input was
dll1
f2
list(8)
it would require me to call f2 with one parameter
how would i call the function without knowing the number of parameters in advance.
further clarification:
how do I write code that will call any
function with all its arguments by building the argument list dynamically
using some other source of information
Since the generated code differs based on the number of parameters, you have two choices: you can write some code in assembly language to do the job (basically walk through the parameter list and push each on the stack before calling the function), or you can create something like an array of pointers to functions, one for each number of parameters you care about (e.g., 0 through 10). Most people find the latter a lot simpler to deal with (if only because it avoids using assembly language at all).
To solve the problem in general you need to know:
The calling conventions (those stdcall, cdecl, fastcall, thiscall (btw, the latter two can be combined in MSVC++), etc things) that govern how the functions receive their parameters (e.g. in special registers, on the stack, both), how they return values (same) and what they are allowed to trash (e.g. some registers).
Exact function prototypes.
You can find all this only in the symbol/debug information produced by the compiler and (likely to a lesser extent) the header file containing the prototypes for the functions in the DLL. There's one problem with the header file. If it doesn't specify the calling convention and the functions have been compiled with non-default calling conventions (via a compiler option), you have ambiguity to deal with. In either case you'll need to parse something.
If you don't have this information, the only option left is reverse engineering of the DLL and/or its user(s).
In order to correctly invoke an arbitrary function only knowing its prototype and calling convention at run time you need to construct code analogous to that produced by the compiler when calling this function when it's known at compile time. If you're solving the general problem, you'll need some assembly code here, not necessarily hand-written, run-time generated machine code is a good option.
Last but not least, you need some code to generate parameter values. This is most trivial with numeric types (ints, floats and the like) and arrays of them and most difficult with structures, unions and classes. Creating the latter on the fly may be at least as difficult as properly invoking functions. Don't forget that they may refer to other objects using pointers and references.
The general problem is solvable, but not cheaply. It's far easier to solve a few simple specific cases and maybe avoid the entire problem altogether by rewriting the functions to have less-variable parameters and only one calling convention OR by writing wrapper functions to do that.
You might want to check out the Named Parameter Idiom.
It uses method chaining to basically accomplish what you want.
It solves the problem where you know what a default set of arguments look like, but you only need to customize a few of them and not necessarily in the order they are declared.
If your clients know at compile-time, then can wrap it this way:
template<class Args...>
void CallFunctionPointer(void* pf, Args&&... args)
{
typedef void(*FunctionType)(Args...);
FunctionType* pf2 = (FunctionType*) pf;
(*pf2)(forward<Args>(args)...);
}
Note, if you pass the wrong number of paramters or the wrong type(s) of parameters behaviour is undefined.
Background:
In C/C++ you can cast a function pointer to any signature you want, however if you get it wrong behavior is undefined.
In your case there are two signatures you have mentioned:
void (*)(int)
and
void (*)(int, int, int)
When you load the function from the DLL it is your responsibility to make sure you cast it to the correct signature, with the correct number and types of parameters before you call it.
If you have control over the design of these functions, I would modify them to take a variable number of arguments. It the base type is always int, than just change the signature of all the functions to:
void (*)(int* begin, size_t n);
// begin points to an array of int of n elements
so that you can safely bind any of the functions to any number of arguments.
Related
I'm calling a function with __func__ as one of the parameters so I can store the name of the function calling that function without having to retype the name of the calling function.
Is there a way of also getting the address of the calling function - a sort of getaddress(__func __) ??
The address will not tell you much; may I instead suggest the predefined macros __FILE__ and __LINE__? They will tell you the current source file (as a char*) and the current line. When you call a function passing those as parameters, you'd know which file/line was the function called from.
They're evaluated by the compiler at the point of usage. If you use them inside the function as opposed to passing them as parameters, they'll tell you the file/line of the function itself.
You can declare function pointers and then assign specific functions to them. So then you could have an array or other collection of such pointers as your table.
If this works for you and you accept the answer, I'm willing to come back and create a short summary here. (I know I'm not supposed to answer with just-a-link.) But see if this approach will do what you want.
https://www.learncpp.com/cpp-tutorial/78-function-pointers/
There is no portable standard C++ way to do this. You could use compiler/OS specific hacks, the same was as in C, but it's less useful in C++ since it only works on extern "C" names (where the __FUNCTION__/__func__ match what dlsym expects).
Since that hack only works on extern "C" names, this means you can't use it for templated functions, class methods, or function overloading (same function name, different argument prototypes), which is fairly restrictive. Mind you, even typing out the function name wouldn't work in some of those cases already (e.g. the name alone doesn't describe the prototype, so function overloading wouldn't work).
I think you need to rethink a design that's essentially demanding reflection in C++; the nature of optimizing compilers is that most of the functions you define don't actually have to exist, or if they do, they exist only with names that are meaningless to anything but the compiler. When you ask to dynamically determine the address of the current function from within the function, you're assuming the function exists, with an actual address, in the final compiled binary, when it could just as easily have been inlined into each actual call site, partially merged with a near identical function, etc.
Suppose I have a variadic function like this:
template <typename... A>
void func(A... args)
{
//Do stuff
}
And I have also a vector like this:
enum Type{
DOUBLE,
STRING
};
std::vector<std::pair<std::string, Type>> varg;
So I want to iterate over the elements of the map and call the templated function with the specified types, like: varg = {{"a", Type::STRING}, {"1.2", Type::DOUBLE}};
should call func("a", 1.2)
Any hints on how to do that?
At the lowest level (C-like), the application binary interface follows some calling conventions, notably how arguments are transmitted to a function, and it usually depends on the type of the argument (often, pointers go in some processor registers and floating point numbers go in some other kind of registers).
If you want to call a function of unknown signature (i.e. you know its signature and the actual arguments and their number only at runtime, not at compile time) you need some ABI specific tricks, and probably some machine specific code. You might consider using the libffi which provides
a portable, high level programming interface to various calling conventions
BTW, you could consider packing or boxing your values in some "universal" container à la boost::any or QVariant or your own tagged unions, or perhaps boost::variant
Perhaps you might want to embed some interpreter in your application, e.g. GNU guile or Lua.
Noticve that for C or C++, functions and function pointers have some compile-time known signature which matters a lot. Calling something with the wrong signature (that is a function whose signature is not the one the compiler expects) is undefined behavior.
You are mixing up compile-time and runtime features here. (Hint: It won't work)
As a thought-experiment:
Suppose you have a std::vector<> of some kind, that is filled with some data, say with N entries. Note that this N is a priori only known at runtime!
Now you want to unpack these N data segments into a variadic template, something that has to be done compile-time! Templates are compile-time features!
This cannot work. You can in principle do something similar if you use compile-time containers (see boost::mpl). But these require, that you know (or can calculate) everything at compile-time.
Also you may want to look at boost::fusion which sort of tries to bridge this gap. Though you should always note that it cannot! Templates are still compile-time only.
I'm experimenting with variable arguments in C++, using va_args. The idea is useful, and is indeed something I've used a lot in C# via the params functionality. One thing that frustrates me is the following excerpt regarding va_args, above:
Notice also that va_arg does not determine either whether the retrieved argument is the last argument passed to the function (or even if it is an element past the end of that list).
I find it hard to believe that there is no way to programmatically determine the number of variable arguments passed to the function from within that function itself. I would like to perform something like the following:
void fcn(int arg1 ...)
{
va_list argList;
va_start(argList, arg1);
int numRemainingParams = //function that returns number of remaining parameters
for (int i=0; i<numRemainingParams; ++i)
{
//do stuff with params
}
va_end(argList);
}
To reiterate, the documentation above suggests that va_arg doesn't determine whether the retrieved arg is the last in the list. But I feel this information must be accessible in some manner.
Is there a standard way of achieving this?
I find it hard to believe that there is no way to programmatically determine the number of variable arguments passed to the function from within that function itself.
Nonetheless, it is true. C/C++ do not put markers on the end of the argument list, so the called function really does not know how many arguments it is receiving. If you need to mark the end of the arguments, you must do so yourself by putting some kind of marker at the end of the list.
The called function also has no idea of the types or sizes of the arguments provided. That's why printf and friends force you to specify the precise datatype of the value to interpolate into the format string, and also why you can crash a program by calling printf with a bad format string.
Note that parameter passing is specified by the ABI for a particular platform, not by the C++/C standards. However, the ABI must allow the C++/C standards to be implementable. For example, an ABI might want to pass parameters in registers for efficiency, but it might not be possible to implement va_args easily in that case. So it's possible that arguments are also shadowed on the stack. In almost no case is the stack marked to show the end of the argument list, though, since the C++/C standards don't require this information to be made available, and it would therefore be unnecessary overhead.
The way variable arguments work in C and C++ is relatively simple: the arguments are just pushed on the stack and it is the callee's responsibility to somewhat figure out what arguments there are. There is nothing in the standard which provides a way to determine the number of arguments. As a result, the number of arguments are determined by some context information, e.g., the number of elements referenced in a format string.
Individual compilers may know how many elements there are but there is no standard interface to obtain this value.
What you could do instead, however, is to use variadic templates: you can determine very detailed information on the arguments being passed to the function. The interface looks different and it may be necessary to channel the arguments into some sort of data structure but on the upside it would also work with types you cannot pass using variable arguments.
No, there isn't. That's why variable arguments are not safe. They're a part of C, which lacks the expressiveness to achieve type safety for "convenient" variadic functions. You have to live with the fact that C contains constructions whose very correctness depends on values and not just on types. That's why it is an "unsafe language".
Don't use variable arguments in C++. It is a much stronger language that allows you to write equally convenient code that is safe.
No, there's no such way. If you have such a need, it's probably best to pack those function parameters in a std::vector or a similar collection which can be iterated.
The variable argument list is a very old concept inherited from the C history of C++. It dates back to the time where C programmers usually had the generated assembler code in mind.
At that time the compiler did not check at all if the data you passed to a function when calling it matched the data types the function expected to receive. It was the programmer's responsibility to do that right. If, for example, the caller called the function with a char and the function expected an int the program crashed, although the compiler didn't complain.
Today's type checking prevents these errors, but with a variable argument list you go back to those old concepts including all risks. So, don't use it if you can avoid it somehow.
The fact that this concept is several decades old is probably the reason that it feels wrong compared to modern concepts of safe code.
What are the benefits of using
variadic functions
void fun(int i, ...);
instead of passing a pointer to an array?
void fun(int i*);
When are variadic functions preferred?
You have to explicitly create the array first. In addition, it would be problematic if you wanted to specify parameters of different types.
Variadic functions do not require creating any array and they can deal with different types.
As an example, I could not bare to use the printf-functions if I always had to create some array first.
On the other hand, in most cases it's just a form of syntactic sugar, I suppose.
Pointer to array assumes predefined type of the parameter (or struct, if its several different types).
Variadic functions are used when you don't know ahead of time what would the type of the parameter be, and you use a hint of the predefined parameters to get that knowledge (like the format string for printf).
Also, you don't want to pass an array in a variadic function, as you would also want to pass in its size. e.g:
myfunction(int *pArray, int NumElements)
The main point, though, is that variadic functions allow many different types to be passed.
I would suggest you to simply not use variadic functions. However they can be useful. For example in template metaprogramming techniques to implement compile-time querys.
As the compiler can't verify that a given call to a variadic
function passes an appropriate number of arguments or that those
arguments have appropriate types. Consequently, a runtime call to a
variadic function that passes inappropriate arguments yields
undefined behavior.
In pure C environments variadic functions have no alternative but in
c++ you are able to find object oriented alternatives (also one
issue).
Variadic functions are not trivial to implement. Failing to initialize ap, calling va_arg() one time to many or omitting the va_end(ap) call can crash your program.
Example of being close to undefined behavior:
It was my job to crate a object-oriented wrapper around the sqlite C api.
Here I am: I created a fancy interface for executing sqlite querys it was something like that:
void Query(const std::string& Query, void* Arguments, ...);
This is on one side awesome and fancy but: You immediately encounter undefined behavior if your parameter types are wrong. For example:
db->Query("select * from northwind where id = ?", "Peter"); // espects int as type
Will result in undefined behavior.
Is there a way to determine how many parameters a Lua function takes just before calling it from C/C++ code?
I looked at lua_Debug and lua_getinfo but they don't appear to provide what I need.
It may seem a bit like I am going against the spirit of Lua but I really want to bullet proof the interface that I have between Lua and C++. When a C++ function is called from Lua code the interface verifies that Lua has supplied the correct number of arguments and the type of each argument is correct. If a problem is found with the arguments a lua_error is issued.
I'd like to have similar error checking the other way around. When C++ calls a Lua function it should at least check that the Lua function doesn't declare more parameters than are necessary.
What you're asking for isn't possible in Lua.
You can define a Lua function with a set of arguments like this:
function f(a, b, c)
body
end
However, Lua imposes no restrictions on the number of arguments you pass to this function.
This is valid:
f(1,2,3,4,5)
The extra parameters are ignored.
This is also valid:
f(1)
The remaining arguments are assigned 'nil'.
Finally, you can defined a function that takes a variable number of arguments:
function f(a, ...)
At which point you can pass any number of arguments to the function.
See section 2.5.9 of the Lua reference manual.
The best you can do here is to add checks to your Lua functions to verify you receive the arguments you expect.
You can determine the number of parameters, upvalues and whether the function accepts variable number of arguments in Lua 5.2, by using the 'u' type to fill nups, nparams, isvararg fields by get_info(). This feature is not available in Lua 5.1.
I wouldn't do this on the Lua side unless you're in full control of Lua code you're validating. It is rather common for Lua functions to ignore extra arguments simply by omitting them.
One example is when we do not want to implement some methods, and use a stub function:
function do_nothing() end
full_api = {}
function full_api:callback(a1, a2) print(a1, a2) end
lazy_impl = {}
lazy_impl.callback = do_nothing
This allows to save typing (and a bit of performance) by reusing available functions.
If you still want to do function argument validation, you have to statically analyze the code. One tool to do this is Metalua.
No, not within standard Lua. And is Aaron Saarela is saying, it is somewhat outside the spirit of Lua as I understand it. The Lua way would be to make sure that the function itself treats nil as a sensible default (or converts it to a sensible default with something like name = name or "Bruce" before its first use) or if there is no sensible default the function should either throw an error or return a failure (if not name then error"Name required" end is a common idiom for the former, and if not name then return nil, "name required" end is a common idiom for the latter). By making the Lua side responsible for its own argument checks, you get that benefit regardless of whether the function is called from Lua or C.
That said, it is possible that your modules could maintain an attribute table indexed by function that contains the info you need to know. It would require maintenance, of course. It is also possible that MetaLua could be used to add some syntax sugar to create the table directly from function declarations at compile time. Before calling the Lua function, you would use it directly to look up any available attributes and use them to validate the call.
If you are concerned about bullet-proofing, you might want to control the function environment to use some care with what (if any) globals are available to the Lua side, and use lua_pcall() rather than lua_call() so that you catch any thrown errors.
The information you ask for is not available in all cases. For example, a Lua function might actually be implemented in C as a lua_CFunction. From Lua code there is no way to distinguish a pure Lua function from a lua_CFunction. And in the case of a lua_CFunction, the number of parameters is not exposed at all, since it's entirely dependent on the way the function is implemented.
On the other hand, what you can do is provide a system for functions writers (be it in pure Lua or in C) to advertise how many parameters their functions expect. After creating the function (function f(a, b, c) end) they would simply pass it to a global function (register(f, 3)). You would then be able to retrieve that information from your C++ code, and if the function didn't advertise its parameters then fallback to what you have now. With such a system you could even advertise the type expected by the parameters.