473,396 Members | 1,784 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Call function at runtime

Hi,

How to call function at runtime,
based on a struct that contains the information for the function call:
struct func_to_call {
int function_id; // function id to call
unsigned int nparams; // number of parameters
unsigned long* parameter; // the parameter(s) to pass
}

to be passed to some function like this one:

call_function( int id, unsigned int nparams, unsigned long* params )
{
// ???
}

*as you can see functions have different number of parameters ( but all
are of type ULONG )
* function are called from a DLL.
* should i call_function via ordinal number?
--
young_leaf

Mar 3 '06 #1
12 5746
leaf wrote:
How to call function at runtime,
based on a struct that contains the information for the function call:
struct func_to_call {
int function_id; // function id to call
unsigned int nparams; // number of parameters
unsigned long* parameter; // the parameter(s) to pass
}

to be passed to some function like this one:

call_function( int id, unsigned int nparams, unsigned long* params )
{
// ???
}

*as you can see functions have different number of parameters ( but all
are of type ULONG )
* function are called from a DLL.
* should i call_function via ordinal number?


I think you need to invest a bit more time at reading about the things
known as "interpreters". Mechanisms for function invocation are very
implementation- and system-specific, if you want to be reasonably
sophisticated.

In most simple cases you create a table of addresses of the functions you
expect to call and then match the function address (pointer) to the ID you
assigned to it.

V
--
Please remove capital As from my address when replying by mail
Mar 3 '06 #2
leaf wrote:
Hi,

How to call function at runtime,
based on a struct that contains the information for the function call:
struct func_to_call {
int function_id; // function id to call
unsigned int nparams; // number of parameters
unsigned long* parameter; // the parameter(s) to pass
}

to be passed to some function like this one:

call_function( int id, unsigned int nparams, unsigned long* params )
{
// ???
}

*as you can see functions have different number of parameters ( but all
are of type ULONG )
* function are called from a DLL.
* should i call_function via ordinal number?
--
young_leaf


Why not just use an STL vector for the parameters and either an array
or STL map of function pointers. I've used methods like this without
much difficulty, (OK I'm geeky about C++), so I suggest you learn about
STL vectors and function pointers.

JB
Mar 3 '06 #3
this article:
http://www.drizzle.com/~scottb/gdc/fubi-paper.htm

seems to be a solution to me,
its about 'Function Binding System'

using a bit of assembly, it calls a function with variable arguments i
think,
here's the code snippet:

DWORD Call_cdecl( const void* args, size_t sz, DWORD func )
{
DWORD rc; // here's our return value...
__asm
{
mov ecx, sz // get size of buffer
mov esi, args // get buffer
sub esp, ecx // allocate stack space
mov edi, esp // start of destination stack frame
shr ecx, 2 // make it dwords
rep movsd // copy params to real stack
call [func] // call the function
mov rc, eax // save the return value
add esp, sz // restore the stack pointer
}
return ( rc );
}

*as you can see its pretty much the one that i need i think,
the line that needs attention is this:
call [func] // call the function

what reference will ensure that that line would call the right
function?
from where?

---
young_leaf

Mar 3 '06 #4
i may have slipped in reading, but i think it uses symbol names
exported with dllexport to allow binding by name to exported symbols?

---
young leaf

Mar 3 '06 #5
leaf wrote:
this article:
http://www.drizzle.com/~scottb/gdc/fubi-paper.htm

seems to be a solution to me,
its about 'Function Binding System'

using a bit of assembly, it calls a function with variable arguments i
think,
here's the code snippet:

DWORD Call_cdecl( const void* args, size_t sz, DWORD func )
{
DWORD rc; // here's our return value...
__asm
First of all, it's "asm" and not "__asm". Second, whatever you think you
know about assembly, has no relevance here. In C++ assembly code is not
standardized. It's totally implementation- and platform-specific.
[...]

*as you can see its pretty much the one that i need i think,
the line that needs attention is this:
call [func] // call the function

what reference will ensure that that line would call the right
function?
from where?


That is _not_defined_. Ask in a newsgroup that deals with your compiler
or with your platform, or both.

V
--
Please remove capital As from my address when replying by mail
Mar 3 '06 #6
leaf wrote:
i may have slipped in reading, but i think it uses symbol names
exported with dllexport to allow binding by name to exported symbols?


Now you're totally off topic.
Mar 3 '06 #7
leaf wrote:
Hi,

How to call function at runtime,
based on a struct that contains the information for the function call:
struct func_to_call {
int function_id; // function id to call
unsigned int nparams; // number of parameters
unsigned long* parameter; // the parameter(s) to pass
}


This is not portable in portable C++. The number of functions passed in
a function call are determined at compile time, and comiple time is
something that occurs prior to execution time. C++ does not define any
way of dynamic compiling and loading.

What you can do is pre-compile some cooked function calls, and have a
big switch statement which selects one of these calls based on the
parameters.

For instance, suppose all the parameters are restricted to type int,
and the only variation is in the parameter number. Then, given a
pointer to the function ptr, and an array of integer arguments
int_arg[], you can do something like:

switch (number_of_arguments) {
case 0:
{
void (*func)() = (void (*)()) ptr;
func();
}
break;
case 1:
{
void (*func)(int) = (void (*)(int)) ptr;
func(int_arg[0]);
}
break;
case 2:
{
void (*func)(int, int) = (void (*)(int, int)) ptr;
func(int_arg[0], int_arg[1]);
}
break;
/* ... other cases ... */
}

This kind of "glue" code can quickly explode in size, since you have to
write the source code for every kind of binary interface you want to
call, include it in the body of the program, and have a way to route
control to it.

There is a library (GNU GPL'ed though!) for constructing C function
argument lists dynamically and calling functions. The name of this
library is "libavcall" and it was originally written by Bill Triggs.

This library defines a set of macros which, loosely speaking, function
as "opposites" to the standard <stdarg.h> macros va_list, va_arg. That
is why the letter "AV" are used to name the library: VA backwards.

When you construct a list with a specific return type and arguments, it
is automagically copmatible with a function which has that signature,
so then all that is needed is a pointer to that function and you can
call it.

The avcall library is not written portably. It contains a lot of
compiler and platform specific code. It has to understand the calling
conventions of the architecture and operating system platform, so that
given any dynamically constructed av_list, it constructs the right kind
of function calling linkage and performs the right kind of cleanup
afterward.

Mar 3 '06 #8
One question:
When a you 'link' a DLL lib ( static linking ) into a Win32 application
for example;
can we call the functions ( we know that exist in the DLL ) via some
low-level means?
will the exported functions have an 'address/pointer or something' with
the application's process space?

to note:
functions that i need to call are from a DLL, exported using dllexport
for instance.

Mar 3 '06 #9
leaf wrote:
One question:
.... for a Win32 newsgroup, not for here.
When a you 'link' a DLL lib ( static linking ) into a Win32 application
for example;
DLL is not static linking (note the 'D'). The DLL's that are specified
on the linker command line when the program is built are still
dynamically loaded with LoadLibrary(). This is called "load time
dynamic linking" by MSDN. That term is used in the FreeLibrary page for
instance.

LoadLibrary will find an library that is already loaded and properly
increment the reference count on the handle. when you are done with
that reference, use FreeLibrary to drop it. This is true whether the
library was load-time linked or whether it was explicitly loaded by a
call to LoadLibrary().

There is also GetModuleHandle which doesn't increment the module
reference count. This is probably okay for those load-time linked
libraries which can be counted upon to remain valid over the lifetime
of the program.
will the exported functions have an 'address/pointer or something' with
the application's process space?
Yes, accessible by GetProcAddress
to note:
functions that i need to call are from a DLL, exported using dllexport
for instance.


That doesn't matter. The issues are the same. You end up with a pointer
to the function. Unless you have some dynamic calling mechanism like
that avcall library, you have to cast that pointer to the right type
and call it with the right arguments. That cast and call are written in
your program and compiled. If you have a small repertoire of type
signatures, you can just write the glue code.

Mar 3 '06 #10
I think you're right, that would end up to a pointer to a function.
What i'm thinking before was the ".lib" file.... sorry.

Now, to get back with the real problem
consider this code:

DispatchFunc( 543, (LPVOID) theParams );
explanation: call function #543 and pass these parameters (theParams )
it knows about the number of parameters as it is stored in a table

If you want you can check this out:
http://www.drizzle.com/~scottb/gdc/fubi-paper.htm
to check about the actual implementation of that function.

Why am i doing this?
1) There are so many functions in the DLL, all i have is the
documentation of the function prototypes ( argument list etc. )
2) FuBi ( Function Binding System ) has promises. It can 'get' the
exported function in a DLL and store it on a Table of functions
(g_Functions)
3) All i have to do is to call DispatchFunction( int serialID, const
void* params )
*g_Functions table is filled at Application startup, i think

Where did i got the data to pass to 'int serialID' and 'const void*
params'?
Its stored in a binary file, which extracted and eventually will have
those data....

---
young_leaf

Mar 3 '06 #11
leaf wrote:
Where did i got the data to pass to 'int serialID' and 'const void*
params'?
Uh, I don't have time to read the whole paper, but it's describing a
crude RPC mechanism which doesn't deal with issues of passing or
returning reference data, or marshalling data between different machine
architectures.

The serialID comes over the network. It is computed on the client side
by fetching the instruction pointer and searching through the client's
g_Functions table! The serialID travels over the network to the RPC
server, where it is used to locate the corresponding and fetch its
machine address.

The client-side functions are just RPC stubs, and so the g_Functions
array in the client contains the addresses of these RPC stubs. On the
server side, the corresponding array (which must be constructed in
exactly the same order) contains the real functions.

Each stub can find itself in the client-side array by computing its own
address from the instruction pointer register and searching through the
table for the nearest address. This is done by the FindFunction()
routine which is not shown. And that is how each stub knows its own
serialID, and also the meta-information about itself, such as the size
of its argument list on the stack.

The void * parameter is just the packaged up arguments which also come
from the client. It's crude. The client stub information from its
function descriptor to know how big the arguments are, and simply takes
a snapshot off the stack. This is sent as part of the RPC packet to the
other side, which copies it to the stack as part of the function
calling mechanism.

All this stuff is quite so Windows-specific, you have to wonder why the
guy is trying to reinvent Microsoft RPC. Even Microsoft weren't that
dumb; they took their RPC from the Distributed Computing Environment
(DCE) project.

If you don't want that, there are other RPC implementations out there,
complete with interface description languages. No need to hack like
this.
From the "Further Work" paper:


you could create a tool to scan windows.h and other header files
and extract the unmangled function prototypes, converting them
into a type library. "

Yes, indeed. You could re-invent RPC-type tools which already exist.
And that's just your "Further Work". Doh!

For instance:

http://www.swig.org/exec.html

If you have work to do, don't waste your time on undergraduate-level
"oh my god I've discovered you can memcpy pieces of a stack to do RPC"
type of stuff.

Mar 4 '06 #12
Both can be regarded as scripting languages, but wow about the
automatic mapping of exported function from a DLL to the Application
(Win32)? with the g_Functions table? ( during application start-up i
presume )

Yes, indeed you're right about the RPC-like behaviour of it with
regards to calling functions over the network...

I tried to see SWIG, i think it gives me the responsibility to create
an "Interface file" to w/c function prototypes are declared,

but
In my target DLL there have function like:
bool set_hardware_setting_a( int register, unsigned long data );
unsigned long read_data_from( int register );
void start_clocking()
etc. <about 800-1000 functions more...>

I could almost rewrite the whole DLL-code by doing that,
What could you suggest?

Mar 4 '06 #13

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

Similar topics

9
by: Dario | last post by:
This is a technical C++ post regarding the Microsoft runtime error R6025 Pure Virtual Function Call that sometime occurs in programs compiled with Microsoft Visual C++ 6.0. Please consider the...
1
by: sunil s via DotNetMonster.com | last post by:
Hi, I've got a native C++ app which calls a 3rd parth .NET DLL using the LoadLibrary/GetProcAddress functions. This works fine when the DLL is located in the app directory, but if I move it out...
9
by: Netocrat | last post by:
Any comments on the correctness of the statements 1, 2a, 2b, 3 and 4 in the code below? If they are correct, then the definition of an object as well as that of an lvalue is broken in C99 by the...
7
by: clusardi2k | last post by:
Hello, I have a shared drive on SGI, Linux, and Windows. A second call to fopen doesn't create the file if it has been deleted. I would like to use fopen for its pointer return value to...
5
by: Kurt Van Campenhout | last post by:
Hi, I am trying to get/set Terminal server information in the active directory on a windows 2000 domain. Since the ADSI calls for TS don't work until W2K3, I need to do it myself. I'm fairly...
5
by: SStory | last post by:
Hi all, I really needed to get the icons associated with each file that I want to show in a listview. I used the follow modified code sniplets found on the internet. I have left in...
3
by: msnews.microsoft.com | last post by:
Hi i am using User32.dll in Visual stdio 2005. public static extern long SetActiveWindow(long hwnd); public static extern long keybd_event(byte bVk, byte bScan, long dwFlags,
5
by: Lee | last post by:
(I also posted this query in Microsoft.Public.DotNet.Framework yesterday, but since I have received no responses, I am posting it here too.) Using Windows XP with all updates applied and Visual...
2
by: Gillard | last post by:
hello I get a dll with standard call in C ++ but I really do not know how to use it in VB anyone can help??? there is the declarations in cpp to use the functions #ifndef SFPDF_H #define...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
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
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
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...

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.