gwu@nujoizey.tcs.com (George Wu) (04/04/91)
In article <1991Apr3.011032.14110@terminator.cc.umich.edu>, normanb@pinhead.citi.umich.edu (David R. Richardson) writes: |> Last week I asked this newsgroup for comments on combining C and |> C++. Here is a summary of replies: |> |> [ . . . stuff deleted . . . ] |> |> For example, cfront performs this initialization by calling a routine, |> "_main()". In translating your C++ code, cfront places a call to this |> routine right after YOUR main(). Correction: _main() is called *before* my/your main(). And to be entirely complete, cleanup code (destructors for static and global objects) need to be called when main() is finished. |> [ . . . more deletions . . . ] |> |> Solutions? There are two general ways around this (neither one of |> which is very elegant). Still another solution is to write your C main() routine as normal, but explicitly call _main() from it: int main(int argc, char *argv[]) { #ifdef __cfront extern int _main(); _main(); #endif // rest of ordinary C main() code } Just be sure to link with the C++ compiler and libC, as several compilers generate additional information at the final link stage. |> This still leaves some problems. What if you want to write a general |> library of routines in C++ that anyone can use? Then that user will |> have to write a dummy C++ main() which calls HER main() which then calls |> YOUR library? Yuck! It seems like there should be a better way... Well, if your C++ routines are strictly routines, ie. not member functions of a class, you can declare them to use C linkage: extern "C" void func(); void func() { // . . . } Of course, this rather restricts what you can do in the C++ library, for instance C linkage implies no parameter overloading. (You couldn't make use of overloading anyways, since your calls would be from a C compiler, which has no concept of overloading.) Another approach might be to define some macros to make writing the C wrapper functions easier: C::func() { // . . . } #define Wrap(className,methodName) \ name2(Wrapper,name2(className,className))(void *object) \ { \ ((className *)object)->methodName(); \ } where name2(x,y) is converted by the cpp into xy (see generic.h, if you've got it). Your C++ method is then callable from C code like this: // assume there's a class Class, with method Function extern WrapperClassFunction(void *object); int func(void *object) { // . . . WrapperClassFunction(object); // . . . } Note that this can still get pretty messy, since you may have to allow for overloading, parameters, etc. George ---- George J Wu, Software Engineer | gwu@tcs.com or uunet!tcs!gwu Teknekron Communications Systems, Inc.| (415) 649-3752 2121 Allston Way, Berkeley, CA, 94704 | Quit reading news. Get back to work.
billri@redwood.sos.ivy.isc.com (Bill Rizzi) (04/05/91)
In article <1990@godzilla.tcs.com>, gwu@nujoizey.tcs.com (George Wu) writes: |> In article <1991Apr3.011032.14110@terminator.cc.umich.edu>, |> normanb@pinhead.citi.umich.edu (David R. Richardson) writes: |> |> Last week I asked this newsgroup for comments on combining C and |> |> C++. Here is a summary of replies: |> |> |> |> [ . . . stuff deleted . . . ] |> |> |> |> For example, cfront performs this initialization by calling a routine, |> |> "_main()". In translating your C++ code, cfront places a call to this |> |> routine right after YOUR main(). |> |> Correction: _main() is called *before* my/your main(). And to be |> entirely complete, cleanup code (destructors for static and global objects) |> need to be called when main() is finished. Actually, cfront (AT&T C++ 2.1) places the call to _main() as the first statement in the definition of C function main(). Just take a peek at the generated C code. You'll see something like: ... main(...) { _main(); ... } I don't know for sure that _main() is standard with all C++ compilers, however. Regarding destructors, the C++ library has an exit() function which takes care of this. So as you pointed out, it is important to link with the C++ libraries. If your main() function is in C, an (early) call to _main() is indeed appropriate. It is probably also a good idea to call exit() explicitly, rather than "falling off" the end of your main() function and relying on the C runtime to call exit(). Bill -- Bill Rizzi INTERACTIVE Systems Corporation billri@ivy.isc.com 26635 W. Agoura Rd, Suite 200 818-880-1200 x2110 Calabasas, CA 91302
steve@taumet.com (Stephen Clamage) (04/06/91)
billri@redwood.sos.ivy.isc.com (Bill Rizzi) writes: > Actually, cfront (AT&T C++ 2.1) places the call to _main() as the >first statement in the definition of C function main(). Just take a peek at >the generated C code. You'll see something like: >... main(...) { _main(); ... } > I don't know for sure that _main() is standard with all C++ >compilers, however. Different C++ compilers have different solutions for this. Some call a function equivalent to _main() but with a different name. Some use other means to achieve runtime initialization of static data. The ANSI C++ committee is addressing possible ways to standardize the static constructor/destructor problem in multilanguage environments. -- Steve Clamage, TauMetric Corp, steve@taumet.com