I need to call a function in a shared library, but the type of the
function is not known until run-time.
enum Type { Void=0, Char, Uchar, Short, Ushort, Int, Uint, Float,
Double, String };
void call_unknown_function(
void *function,
enum Type retType, void *retAddress,
...);
The variable arguments are pairs of (Type,pointer), terminated by 0. So
to call double sqrt(double), it would be
double result, n=2.0;
call_unknown_function(sqrt, Double, &result, Double, &n, 0);
So how could I implement such a function? I would prefer not to resort
to assembly language.
Cheers,
Calum 4 3720
Calum wrote: I need to call a function in a shared library, but the type of the function is not known until run-time.
enum Type { Void=0, Char, Uchar, Short, Ushort, Int, Uint, Float, Double, String };
void call_unknown_function( void *function, enum Type retType, void *retAddress, ...);
The variable arguments are pairs of (Type,pointer), terminated by 0. So to call double sqrt(double), it would be
double result, n=2.0; call_unknown_function(sqrt, Double, &result, Double, &n, 0);
So how could I implement such a function? I would prefer not to resort to assembly language.
C's "code model" is static: the language provides no means
to create and execute code at run-time. In particular, the
language provides no means to generate and execute an arbitrary
function call at run-time.
If the set of "signatures" -- combinations of result types
and argument lists -- is small, you can use the Type values to
select one of several pre-written calls and execute that one:
switch (result_Type) {
case Int:
switch (argument_signature) {
case Empty:
int_result = ((int)(*)(void)) fptr(void);
break;
case One_Int:
int_result = ((int)(*)(int)) fptr(int_arg[0]);
break;
case One_Double:
int_result = ((int)(*)(double)) fptr(dbl_arg[0]);
break;
case Int_and_Double:
int_result = ((int)(*)(int,double))
fptr(int_arg[0], dbl_arg[1]);
break;
.... and so on. (Obviously, there's code in addition to this snip.)
Note the casts of the function pointer argument: at the point of
the call, the pointer type must agree with the actual function
being called. And since there's no "generic" function pointer
akin to `void*' for object pointers, call_unknown_function() must
be defined as taking some specific function pointer type, and the
call to call_unknown_function() must cast the actual function pointer
to that type, e.g.:
void call_unknown_function(void (*fptr)(void), ...);
call_unknown_function( (void (*)(void))sqrt,
Double, &result, Double, &n, 0);
All in all, it's not an entirely satisfactory solution: it's
inflexible, error-prone, and prolix. Although I've used the
technique, I'd suggest you seek alternative approaches to solve
whatever your over-arching problem may be; almost anything is
better than this kind of mess.
-- Er*********@sun.com
Calum wrote: I need to call a function in a shared library, but the type of the function is not known until run-time.
enum Type { Void=0, Char, Uchar, Short, Ushort, Int, Uint, Float, Double, String };
void call_unknown_function( void *function, enum Type retType, void *retAddress, ...);
The variable arguments are pairs of (Type,pointer), terminated by 0. So to call double sqrt(double), it would be
double result, n=2.0; call_unknown_function(sqrt, Double, &result, Double, &n, 0);
So how could I implement such a function? I would prefer not to resort to assembly language.
Cheers, Calum
Oops, it's in the faq. I did not expect this :-)
So I now have some info to get started with. Though, I am using
Microsoft C++, so has anyone had any specific success doing this on that
compiler, I would like to hear about it.
Cheers,
Calum
Calum wrote: I need to call a function in a shared library, but the type of the function is not known until run-time.
enum Type { Void=0, Char, Uchar, Short, Ushort, Int, Uint, Float, Double, String };
void call_unknown_function( void *function, enum Type retType, void *retAddress, ...);
The variable arguments are pairs of (Type,pointer), terminated by 0. So to call double sqrt(double), it would be
double result, n=2.0; call_unknown_function(sqrt, Double, &result, Double, &n, 0);
So how could I implement such a function? I would prefer not to resort to assembly language.
Cheers, Calum
Pass a pointer to data and an identifier indicating the data's type.
Use a switch statement or lookup table to defer execution to an
appropriate function will dereference the pointer correctly.
#include <stdio.h>
#include <stdlib.h>
enum Variable_type{VAR_VOID, VAR_CHAR, VAR_UCHAR, /* ... */};
void add_char(const void * ptr_to_first_argument,
const void * ptr_to_second_argument,
void * ptr_to_result)
{
char first_argument;
char second_argument;
char * p_result;
first_argument = *((char *) ptr_to_first_argument);
second_argument = *((char *) ptr_to_second_argument);
p_result = (char *) ptr_to_result;
*p_result = first_argument + second_argument;
return;
}
void add(enum Variable_Type variable_ID,
const void * ptr_to_first_argument,
const void * ptr_to_second_argument,
void * ptr_to_to_result)
{
switch (variable_ID)
{
case VAR_CHAR:
add_char(ptr_to_first_argument, ptr_to_second_argument,
ptr_to_ptr_to_result);
break;
/* etc. */
}
return;
}
int main(void)
{
char a = 5;
char b = 11;
char result;
add(VAR_CHAR, &a, &b, &result);
printf("%d + %d == %d\n", a, b, result);
return EXIT_SUCCESS;
}
--
Thomas Matthews
C++ newsgroup welcome message: http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq: http://www.raos.demon.uk/acllc-c++/faq.html
Other sites: http://www.josuttis.com -- C++ STL Library book
Calum wrote: I need to call a function in a shared library, but the type of the function is not known until run-time.
enum Type { Void=0, Char, Uchar, Short, Ushort, Int, Uint, Float, Double, String };
void call_unknown_function( void *function, enum Type retType, void *retAddress, ...);
The variable arguments are pairs of (Type,pointer), terminated by 0. So to call double sqrt(double), it would be
double result, n=2.0; call_unknown_function(sqrt, Double, &result, Double, &n, 0);
I have a solution to this problem. In C, the alternatives are
- Use a large switch statement (portable, tedious, always incomplete)
- Hack the stack (tedious, not portable)
However I have devised a portable solution in C++ involving templates.
Since this is a C group, I won't post it in its entirety, the code can
be found at http://visula.org/calum/dynargs.zip
The resulting library can however be called from C. This is (bizarrely)
an example of a C library being implemented in C++, usually it is the
other way around.
e.g.
double x, y=49.0;
dyn_apply(sqrt, double_t, &x, double_t, &y, 0);
// x = 7.0
Calum This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: jim.brown |
last post by:
Please refer me to the right place if this is the wrong place to post
this question.
I'm looking for an example of calling the Eigenvalue routines of JAMA
from a C++ program. The documentation...
|
by: WittyGuy |
last post by:
Hi,
What is the major difference between function overloading and function
templates?
Thanks!
http://www.gotw.ca/resources/clcm.htm for info about ]
|
by: Marek Lewczuk |
last post by:
Hello,
I'm moving out from MySQL to PostgreSQL and there are some function
which are not supported in PG so I'm trying to write my own functions.
Currently I have big problem with function IF(),...
|
by: Richard Hayden |
last post by:
Hi,
I've just upgraded my gcc and I'm currently trying to compile some code for
my own operating system kernel, but I am getting an error of "Undefined
reference to `memcpy`" when I try to link...
|
by: Tim Nelson |
last post by:
Can you lend a hand?
Newbie here ....trying to call a C# COM object (error is below):
****** C# DLL ********
namespace ECSLink
{
public class ECSInvoke
{
public void PrintString(string...
| |
by: Jesse McGrew |
last post by:
Hi all,
I'm trying to make a plugin DLL for a third-party application, using
VC++ .NET 2003. This DLL acts as a bridge between the C++ plugin API of
the application, and my actual plugin code...
|
by: John Friedland |
last post by:
My problem: I need to call (from C code) an arbitrary C library
function, but I don't know until runtime what the function name is,
how many parameters are required, and what the parameters are. I...
|
by: MLH |
last post by:
I have the following saved UNION query named qryPeople2NameInNPaperAd:
SELECT & " " & & " " &
& " " & & ", " & & "
" & AS Item, tblVehicleJobs.VehicleJobID
FROM tblVehicleJobs INNER...
|
by: unauthorized |
last post by:
The short story:
I need to be able to cast a function pointer for any function and class to an intermediate type, so I could call it from any point of my program using the "__asm call" instruction....
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
| |
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |