473,506 Members | 16,994 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Calling a function of unknown type

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
Nov 14 '05 #1
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
Nov 14 '05 #2
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
Nov 14 '05 #3
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

Nov 14 '05 #4
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
Nov 14 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

10
3189
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...
16
16201
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 ]
9
13709
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(),...
7
12042
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...
1
1537
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...
1
2881
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...
18
4311
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...
4
1509
by: MLH | last post by:
I have the following saved UNION query named qryPeople2NameInNPaperAd: SELECT & " " & & " " & & " " & & ", " & & " " & AS Item, tblVehicleJobs.VehicleJobID FROM tblVehicleJobs INNER...
2
5314
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....
0
7218
marktang
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,...
0
7307
Oralloy
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,...
0
7478
tracyyun
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...
1
5035
isladogs
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...
0
4701
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...
0
3188
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...
0
3177
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1532
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 ...
1
755
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.