 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Bernd M?ller-Zimmermann Guest
|
Posted: Sat Feb 28, 2004 4:19 am Post subject: Calling an unknown set of separately compiled functions. |
|
|
Hello.
Can I somehow construct a main program to call an
unknown set of functions one after the other, which
which have been compiled and linked in from separate
files?
I have a set of files, each containing a test function.
E.g. the file "test1.cc", "test2.cc", "test3.cc" ... asf
They might contain functions like 'test1()', 'test2()' ...
Say that I want to execute just test #3, #6 and #7.
I could compile as
g++ -o main main.cc test3.cc test6.cc test7.cc
But each time I would have to rebuild "main.cc" to call
the appropriate set of functions.
Although this can be done easily, I'm still curious if
there is some C++ trickery to call an arbitrary set of
'test*()' functions compiled separately and linked with
"main.o".
The individual testcases files are generated by a tool,
but I would not want to put any information about the
"neighboring" testcases into a generated testcase file.
Thanks a lot.
Bernd
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Sat Feb 28, 2004 3:32 pm Post subject: Re: Calling an unknown set of separately compiled functions. |
|
|
In message <9034d894.0402271139.2b5ac2f2 (AT) posting (DOT) google.com>, Bernd
M?ller-Zimmermann <Bernd.temporary1 (AT) gmx (DOT) de> writes
| Quote: | Can I somehow construct a main program to call an
unknown set of functions one after the other, which
which have been compiled and linked in from separate
files?
I have a set of files, each containing a test function.
E.g. the file "test1.cc", "test2.cc", "test3.cc" ... asf
They might contain functions like 'test1()', 'test2()' ...
Say that I want to execute just test #3, #6 and #7.
I could compile as
g++ -o main main.cc test3.cc test6.cc test7.cc
But each time I would have to rebuild "main.cc" to call
the appropriate set of functions.
Although this can be done easily, I'm still curious if
there is some C++ trickery to call an arbitrary set of
'test*()' functions compiled separately and linked with
"main.o".
The individual testcases files are generated by a tool,
but I would not want to put any information about the
"neighboring" testcases into a generated testcase file.
|
Declare a list of function pointers and have main() iterate through the
list calling each in turn. Arrange that each test.cpp contains code to
register its function in the list.
This has a constraint and a problem.
1) All the functions must have the same signature
2) At present C++, AFAIK, has no way to force the registration to happen
in a timely way. A proposal to provide such a mechanism is being
actively debated within the UK.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Stephen C. Dewhurst Guest
|
Posted: Sun Feb 29, 2004 3:00 am Post subject: Re: Calling an unknown set of separately compiled functions. |
|
|
On 27 Feb 2004 23:19:41 -0500, [email]Bernd.temporary1 (AT) gmx (DOT) de[/email] (Bernd
M?ller-Zimmermann) wrote:
| Quote: | Can I somehow construct a main program to call an
unknown set of functions one after the other, which
which have been compiled and linked in from separate
files?
|
I'm sure there are many ways to do this. One "traditional" way is to
use runtime static initialization to build up a data structure that
can then be accessed when main is called. For example, you could
arrange to create a list of function pointers:
struct List {
List *n_;
void (*fp_)();
static List *root_;
};
Each file containing a test function would register itself on the list
at runtime static initialization time by including code similar to
(but better written than) this:
void test1() {
std::cout << "test1" << std::endl;
}
namespace {
struct Init {
Init() {
List *newNode = new List;
newNode->fp_ = test1;
newNode->n_ = List::root_;
List::root_ = newNode;
}
} init;
}
The main program could travers the list and execute any test functions
that registered themselves.
for( List *n = List::root_; n; n = n->n_ )
(*n->fp_)();
There are many more involved variants of this technique that can
handle functions of different signatures, adding new functions or
class types to running programs, etc.
Steve
Steve Dewhurst
www.semantics.org
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Antoun Kanawati Guest
|
Posted: Sun Feb 29, 2004 3:37 am Post subject: Re: Calling an unknown set of separately compiled functions. |
|
|
Another more involved approach is to use dynamic loading.
Compile the test*.cc's into one or more shared libraries,
and use the shared library facilities to load them, look
them up, and call them.
This is strictly outside the language standard, which does
not talk about such things. However, this sort of stuff
works well on most modern platforms (Linux, Win32, and many
unixes).
The proposed technique below (from Francis) also works well,
and I have used it well over 10 years ago. In this case,
you'll have to depend on some static objects, and the static
initializers to get the functions "registered". As far as
I know, the static initializers would all have run by the
time main() starts working; hence, I am puzzled about the
"timely manner" reservation.
In either case, all functions must have the same signature.
With the shared library approach, you will have more headaches;
at least, your functions must be extern "C", so that you can
have a reasonable chance of figuring out their names for lookup.
Francis Glassborow wrote:
| Quote: | In message <9034d894.0402271139.2b5ac2f2 (AT) posting (DOT) google.com>, Bernd
M?ller-Zimmermann <Bernd.temporary1 (AT) gmx (DOT) de> writes
Can I somehow construct a main program to call an
unknown set of functions one after the other, which
which have been compiled and linked in from separate
files?
I have a set of files, each containing a test function.
E.g. the file "test1.cc", "test2.cc", "test3.cc" ... asf
They might contain functions like 'test1()', 'test2()' ...
Say that I want to execute just test #3, #6 and #7.
I could compile as
g++ -o main main.cc test3.cc test6.cc test7.cc
But each time I would have to rebuild "main.cc" to call
the appropriate set of functions.
Although this can be done easily, I'm still curious if
there is some C++ trickery to call an arbitrary set of
'test*()' functions compiled separately and linked with
"main.o".
The individual testcases files are generated by a tool,
but I would not want to put any information about the
"neighboring" testcases into a generated testcase file.
Declare a list of function pointers and have main() iterate through the
list calling each in turn. Arrange that each test.cpp contains code to
register its function in the list.
This has a constraint and a problem.
1) All the functions must have the same signature
2) At present C++, AFAIK, has no way to force the registration to happen
in a timely way. A proposal to provide such a mechanism is being
actively debated within the UK.
|
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Sun Feb 29, 2004 4:40 pm Post subject: Re: Calling an unknown set of separately compiled functions. |
|
|
In message <i530c.431187$na.1021104@attbi_s04>, Antoun Kanawati
<antounk (AT) comcast (DOT) net> writes
| Quote: | The proposed technique below (from Francis) also works well,
and I have used it well over 10 years ago. In this case,
you'll have to depend on some static objects, and the static
initializers to get the functions "registered". As far as
I know, the static initializers would all have run by the
time main() starts working; hence, I am puzzled about the
"timely manner" reservation.
|
Because that actual requirement (in order to accommodate dynamic
loading) allows compilers to be too aggressive in optimising TU's that
seem to be never used.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Sun Feb 29, 2004 5:36 pm Post subject: Re: Calling an unknown set of separately compiled functions. |
|
|
Francis Glassborow <francis (AT) robinton (DOT) demon.co.uk> wrote:
| Quote: | In message <9034d894.0402271139.2b5ac2f2 (AT) posting (DOT) google.com>, Bernd
M?ller-Zimmermann <Bernd.temporary1 (AT) gmx (DOT) de> writes
Can I somehow construct a main program to call an
unknown set of functions one after the other, which
which have been compiled and linked in from separate
files?
I have a set of files, each containing a test function.
E.g. the file "test1.cc", "test2.cc", "test3.cc" ... asf
They might contain functions like 'test1()', 'test2()' ...
Say that I want to execute just test #3, #6 and #7.
I could compile as
g++ -o main main.cc test3.cc test6.cc test7.cc
But each time I would have to rebuild "main.cc" to call
the appropriate set of functions.
Although this can be done easily, I'm still curious if
there is some C++ trickery to call an arbitrary set of
'test*()' functions compiled separately and linked with
"main.o".
The individual testcases files are generated by a tool,
but I would not want to put any information about the
"neighboring" testcases into a generated testcase file.
Declare a list of function pointers and have main() iterate through the
list calling each in turn. Arrange that each test.cpp contains code to
register its function in the list.
This has a constraint and a problem.
1) All the functions must have the same signature
2) At present C++, AFAIK, has no way to force the registration to happen
in a timely way. A proposal to provide such a mechanism is being
actively debated within the UK.
Solution with no argumenst to the functions is to write a creation |
program that creates a short and simple file containing extern
statements and a global array of function pointers which it initializes.
no functions,classes just a null pointer terminated array of function
pointers. Then main just loops till the function pointer is zero. If
you have make [op has gcc so probably has make] this can be automated
like this:
TEST_OBJS = test1.o test2.o test4.o
init_funcs.o: $(TEST_OBJS)
make_init $(TEST_OBJS) >int_funcs.cc
gcc -c -o init_funcs.o init_funcs.cc
test_bed_1: $(TEST_OBJS) main.o init_funcs.o
gcc -o test_bed_1 $(TEST_OBJS) main.o init_funcs.o $(LIBS)
make_init would generate a file like:
extern void test1();
extern void test2();
extern void test4();
typedef void (*FUNC)();
FUNC func[] = {
test1,
test2,
test4,
0};
//end of file.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dylan Nicholson Guest
|
Posted: Mon Mar 01, 2004 12:28 pm Post subject: Re: Calling an unknown set of separately compiled functions. |
|
|
[email]Bernd.temporary1 (AT) gmx (DOT) de[/email] (Bernd M?ller-Zimmermann) wrote in message news:<9034d894.0402271139.2b5ac2f2 (AT) posting (DOT) google.com>...
| Quote: | Hello.
Can I somehow construct a main program to call an
unknown set of functions one after the other, which
which have been compiled and linked in from separate
files?
I hoped that a slightly questionable abuse of 'atexit' might do the |
trick:
struct register_func
{
register_func(void (*func)()) { atexit(func); }
};
[in test1.cc:]
void test1()
{
std::cout << "this is test1()" << std::endl;
}
static register_func rf(test1);
But unfortunately at least under some compilers std::cout is not in a
valid state by the time this is called (which surprises me a little -
I would have thought application-registered atexit functions would be
called before library ones). Still it might work for you.
If you did it yourself with a standard container of function pointers,
e.g.:
typedef void (*proc_t)();
typedef std::list
Then ideally you could write:
proc_list plist;
std::for_each(plist.begin(), plist.end(), BIND(operator ()));
For some definition of BIND that I suspect is not actually possible
(happy to be proven wrong though!).
Dylan
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Bernd M?ller-Zimmermann Guest
|
Posted: Tue Mar 02, 2004 11:29 am Post subject: Re: Calling an unknown set of separately compiled functions. |
|
|
Francis Glassborow <francis (AT) robinton (DOT) demon.co.uk> wrote
| Quote: | In message <9034d894.0402271139.2b5ac2f2 (AT) posting (DOT) google.com>, Bernd
M?ller-Zimmermann <Bernd.temporary1 (AT) gmx (DOT) de> writes
Can I somehow construct a main program to call an
unknown set of functions one after the other, which
which have been compiled and linked in from separate
files?
Declare a list of function pointers and have main() iterate through the
list calling each in turn. Arrange that each test.cpp contains code to
register its function in the list.
|
"static initialization": that was the thing I was looking for and forgot.
Have each "test*.cc" contain something like
int register_func(void (*f)());
void test1() {
// ...
}
static int dummy = register_func(test1);
Where 'register_func()' would insert the function pointer into
the list of functions to be called from main. (Of course you could
still make this up more or less elegant...)
Thanks Francis and all the others who responded.
Bernd
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|