eggberd@.uni-paderborn.de (Bernd Eggert) (02/12/91)
This message is posted for someone who cannot post to the net himself. Please respond to the net or to axel@cadlab.cadlab.de ! ------------------------------------------------------------- I have a question concerning the combination of C and C++. Assume the following situation: You want to write a library in C++. People working with your library should be able to use it either from C++ or from C. In order to make functions callable from C you use the 'extern "C"' directive. With this directive you can write ordinary C functions 'around' the C++ objects. These functions can be called from a C program. The problem occurs when you try to link the C program with the C++ library. The normal linker does not care for constructors or destructors and therefore static objects will not be initialized. Is there an elegant and portable way to solve this problem? We are interested in solutions for AT&T CC and g++. Below is an example which works if you use the C++-linker (but not with a normal linker) Thanks for any help. ------------------------------------------------------------------------------- File 'hello.C': ------------------------------------------------------------------------------- /* this is a C++ class to be used by a C program */ #include <stream.h> #include <string.h> #include <stdio.h> class hello { private: char name[20]; public: hello(char *n) { strcpy(name,n); } void print() { cout << "Hello " << name << "\n"; /* cout requires initialization */ printf("Hello %s\n",name); /* printf is no problem */ } }; /* these functions enable the non-C++-user to use the class 'hello': */ extern "C" { void *create_person(char *n) { return((void *)new hello(n)); } void print_person(void *p) { ((hello *)p)->print(); } } ------------------------------------------------------------------------------- File 'chello.c' ------------------------------------------------------------------------------- /* this is a C program dealing with a C++ object */ void *create_person(char *n); void print_person(void *p); main() { void *p; __main(); /* this is necessary for initializing static objects in g++ */ p = create_person("Henry"); print_person(p); } ------------------------------------------------------------------------------- File 'makefile': ------------------------------------------------------------------------------- chello: chello.o hello.o g++ -o chello chello.o hello.o chello.o: chello.c gcc -c chello.c hello.o: hello.C g++ -c hello.C ------------------------------------------------------------------------------- Axel Meckenstock CADLAB University of Paderborn phone : +49 5251 284-120 Siemens Nixdorf Information Systems fax : +49 5251 284-140 Bahnhofstr. 32 email : axel@cadlab.cadlab.de D-4790 Paderborn -------------------------------------------------------------------------------
don@zardoz.coral.com (Don Dewar) (02/21/91)
) Resent-From: uunet!ai.mit.edu!gnulists ) Return-Path: <gnulists@ai.mit.edu> ) Resent-Date: 12 Feb 91 15:10:07 GMT ) Date: 12 Feb 91 15:10:07 GMT ) From: uunet!.uni-paderborn.de!eggberd (Bernd Eggert) ) Sender: uunet!ai.mit.edu!gnulists ) Organization: Uni-GH Paderborn, West Germany ) Subject: Combination of C and C++ ) To: help-g++@prep.ai.mit.edu ) ) ) This message is posted for someone who cannot post to the net himself. ) ) Please respond to the net or to axel@cadlab.cadlab.de ! ) ) ------------------------------------------------------------- ) I have a question concerning the combination of C and C++. ) ) ) Assume the following situation: ) ) You want to write a library in C++. People working with your library should be ) able to use it either from C++ or from C. ) ) In order to make functions callable from C you use the 'extern "C"' directive. ) With this directive you can write ordinary C functions 'around' the C++ ) objects. These functions can be called from a C program. ) ) The problem occurs when you try to link the C program with the C++ library. ) The normal linker does not care for constructors or destructors and therefore ) static objects will not be initialized. ) ) Is there an elegant and portable way to solve this problem? We are interested ) in solutions for AT&T CC and g++. ) ) Below is an example which works if you use the C++-linker (but not with ) a normal linker) ) ) Thanks for any help. ) ) ------------------------------------------------------------------------------- ) File 'hello.C': ) ------------------------------------------------------------------------------- ) ) /* this is a C++ class to be used by a C program */ ) ) #include <stream.h> ) #include <string.h> ) #include <stdio.h> ) ) ) class hello ) { ) private: ) char name[20]; ) ) public: ) hello(char *n) ) { ) strcpy(name,n); ) } ) ) void print() ) { ) cout << "Hello " << name << "\n"; /* cout requires initialization */ ) printf("Hello %s\n",name); /* printf is no problem */ ) } ) }; ) ) ) /* these functions enable the non-C++-user to use the class 'hello': */ ) ) extern "C" ) { ) ) void *create_person(char *n) ) { ) return((void *)new hello(n)); ) } ) ) void print_person(void *p) ) { ) ((hello *)p)->print(); ) } ) ) } ) ) ------------------------------------------------------------------------------- ) File 'chello.c' ) ------------------------------------------------------------------------------- ) ) /* this is a C program dealing with a C++ object */ ) ) ) void *create_person(char *n); ) void print_person(void *p); ) ) ) main() ) { ) void *p; ) ) __main(); /* this is necessary for initializing static objects in g++ */ ) ) p = create_person("Henry"); ) ) print_person(p); ) } ) ) ------------------------------------------------------------------------------- ) File 'makefile': ) ------------------------------------------------------------------------------- ) ) chello: chello.o hello.o ) g++ -o chello chello.o hello.o ) ) chello.o: chello.c ) gcc -c chello.c ) ) hello.o: hello.C ) g++ -c hello.C ) ) ) ------------------------------------------------------------------------------- ) Axel Meckenstock CADLAB ) University of Paderborn ) phone : +49 5251 284-120 Siemens Nixdorf Information Systems ) fax : +49 5251 284-140 Bahnhofstr. 32 ) email : axel@cadlab.cadlab.de D-4790 Paderborn ) ------------------------------------------------------------------------------- ) ) ) ) In the case of g++, you must use the g++ linker. I don't find that particularly unportable, just a little inconvenient for those persons that want to link with you library and don't have the linker. In the case of CFront, I don't think you have a problem. CFront just creates "C" code that is compiled and should act just like a normal "C" program with name mangling. I would point out, however, that distributing C++ binary libraries can be a problem in general for a couple of reasons. If the user wants to add to the library, they may want to add a new virtual function at a root class, which throws off the virtual tables. The user must use the C++ compiler used to generate the libraries if they are linking in more C++ code that calls the library, because the name mangling scheme between the two compilers is likely to be different. I just thought I might pass that on to you. Good luck! +---------+ | Coral | |@@@@@*@**| |@@*@@**@@| Don Dewar |*@@**@@@@| Coral Network Corporation, Marlborough, MA |@***@@@@@| Internet: don@coral.com |@@**@@@@@| Phone: (508) 460-6010 |*********| Fax: (508) 481-6258 |Networks | +---------+
jj00@eurotherm.co.uk (John Juer) (02/27/91)
(I can't reach axel@cadlab.cadlab.de) If you are using a C++ library, use "collect" to create an object file with the constructor/destructor bits and put it in the library. The the C linker should pick it up. jj00@uk.co.eurotherm