Topic: A method for calling functions from a C++ library from a C main()?
Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Fri, 19 Nov 1993 09:40:54 GMT Raw View
In article <TOM.93Nov15152109@tom.mvision.com> tom@mvision.com (TOM) writes:
>
> I have been successfully calling C++ routines from a C main
>program, and I would like to trot this method out and see if
>it is portable and complies with the standard.
What made you think that this was in any way difficult??
All you had to do was to declare the C++ functions that you wanted to call
as `extern "C"'.
What's the big deal?
(Maybe you just need a good C++ book.)
--
-- Ronald F. Guilmette, Sunnyvale, California -------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------
Author: tom@mvision.com (TOM)
Date: Mon, 15 Nov 1993 20:21:09 GMT Raw View
I have been successfully calling C++ routines from a C main
program, and I would like to trot this method out and see if
it is portable and complies with the standard.
It seems to me that the two problems involved are
1) linking to "mangled" C++ names from C, and
2) initializers for static objects and static class members (simply
called "statics" for the purposes of this discussion.)
The solution for 1) appears clear from the ANR: wrapper functions
in the C++ files are instantiaed as
extern "C" function( arguments ) { statements }
Since C++ classes can't be directly referenced in C, I use void*
as a surrogate for object pointers, even though it's not typesafe.
I had more of a problem with 2), but I am using the following
conventions, which appear to work.
1) All statics are declared as pointers: initializers are replaced
with explicit calls to new.
2) Each class with static members has a method called init_static() which
explicitly calls new for each of the static pointers in this class.
A "C" wrapper is created for this method.
Static objects that aren't class members can be handled in two different
ways. If they are truly global in nature, they can be initialized in
a global function STATIC_GLOBAL_init_static(). However, I have found
that every static in my code is really associated with a specific class,
and that the initializer can be part of the initializer of that class.
Example:
(in C world)
typedef void* FRED_PTR; /* "Really" a pointer to a C++ object. */
void FRED_init_static( ); /* called to initialize static members */
void FRED_method( FRED_PTR ); /* Wrapper for C++ method. */
FRED_PTR FRED_new(); /* Wrapper for "new" function. */
(in C++ world)
class BARNEY;
class FRED {
public:
void init_static();
void method() { /* ... */ }
private:
static BARNEY* barney;
};
// Static object that belongs to FRED.
//
static GENERIC_QUEUE* queue_of_freds = new GENERIC_QUEUE( sizeof( FRED ));
BARNEY* FRED::barney = new BARNEY; // Static variable is a pointer.
void FRED::init_static() {
barney = new BARNEY; // Duplicate of initializers.
queue_of_freds = new GENERIC_QUEUE( sizeof( FRED ));
}
extern "C" void FRED_init_static() {
FRED::init_static(); // External wrapper for initializer.
}
extern "C" void FRED_method( FRED_PTR fake_fred ) {
FRED* fred = (FRED*) fake_fred; // Method call for FRED.
fred->method();
}
extern "C" FRED_PTR FRED_new() {
return (FRED_PTR) new FRED; // Create a new FRED.
}
This all appears to work very well. C never calls the constructors,
but the client C program called CLASS_init_static for each class that
it uses.
My questions are
a) Is this ridiculous? Am I going about this in a circuitous way?
b) Is there any way to get a hold of the code for the constructors for
these static variables, so that I could explicitly call these
constructors?
--
/t
Tom Ritchford Market Vision, 40 Rector Street, NYC 10006
tom@mvision.com (212) 227-1610 (W) (718) 384-5716 (H)
Send your snail mail address for a free subscription to
"The Journal of Pataphysical Reviews"