There is a man here trying to link c++ code with a c program. He has
read in the sparc compiler manuals that this is possible, but hasn't
been able to get it to work. I don't have the experience to help him
so I am posting this message to the net in hopes that someone that has
done this will respond.
Attached to this message is a share file with the source code he is
trying this with. The messages he gets from the link process are:
> cc -g -c test.c
> CC -g -c wrapper.cc
> cc test.o wrapper.o -o test
> Undefined first referenced
> symbol in file
> cout wrapper.o
> __0OnwUi wrapper.o
> __0FEendlR6Hostream wrapper.o
> __0oNIostream_initctv wrapper.o
> _pure_error_ wrapper.o
> __0oNIostream_initdtv wrapper.o
> __0OdlPv wrapper.o
> __0fOunsafe_ostreamGoutstrPCcTB wrapper.o
> ld: fatal: Symbol referencing errors. No output written to test
> *** Error code 1
> make: Fatal error: Command failed for target `test'
to him or email him directly at kgw...@fep1.rl.gov.
Thanks,
Don
don_br...@fep1.rl.gov
===========================begin share file============================
# To unbundle, sh this file
echo C.h 1>&2
cat >C.h <<'End of C.h'
// C.h -- Abstract base class for testing C wrappers for C++
// (c) 1994 WHC, by Kevin Walker
// Version: 12/08/94
#if !defined( __C_H )
#define __C_H // prevent multiple includes
// class: C ***************************************************************
class C
{
public :
// Constructor
C(void) {}
// Destructor
virtual ~C(void) {}
// Return the class name.
virtual const char *className(void) { return "C"; }
// Some pure virtual functions.
virtual void f(void) = 0;
virtual void g(void) = 0;
// end of C.h *************************************************************
End of C.h
echo C1.h 1>&2
cat >C1.h <<'End of C1.h'
// C1.h -- derived class for C wrappers for C++ example
// (c) 1994 WHC
// Version: 12/08/94
#if !defined( __C1_H )
#define __C1_H // prevent multiple includes
// include files **********************************************************
#include <iostream.h>
#include "C.h" // parent
// class: C1 **************************************************************
class C1 : public C
{
public :
// Constructor
C1(void) : C() {}
// Destructor
virtual ~C1(void) {}
// Return the class name.
virtual const char *className(void) { return "C1"; }
// Implement f() and g()
virtual void f(void) { cout << C1::className() << "::f()" << endl; }
virtual void g(void) { cout << C1::className() << "::g()" << endl; }
// end of C1.h ************************************************************
End of C1.h
echo C2.h 1>&2
cat >C2.h <<'End of C2.h'
// C2.h -- derived class for C wrappers for C++ example
// (c) 1994 WHC
// Version: 12/08/94
#if !defined( __C2_H )
#define __C2_H // prevent multiple includes
// include files **********************************************************
#include <iostream.h>
#include "C.h"
// class: C2 **************************************************************
class C2 : public C
{
public :
// Constructor
C2(void) : C() {}
// Destructor
virtual ~C2(void) {}
// Return the class name.
virtual const char *className(void) { return "C2"; }
// Implement f() and g()
virtual void f(void) { cout << C2::className() << "::f()" << endl; }
virtual void g(void) { cout << C2::className() << "::g()" << endl; }
// end of C2.h ************************************************************
End of C2.h
echo wrapper.h 1>&2
cat >wrapper.h <<'End of wrapper.h'
/* wrapper.h -- C wrappers for C++ class methods
(c) 1994 WHC
Version: 12/08/94
*/
#if !defined( __WRAPPER_H )
#define __WRAPPER_H // prevent multiple includes
#if defined( __cplusplus )
extern "C" {
#endif
/* typedef: CPtr *********************************************************/
/* Wrapper type for classes derived from class C */
typedef void *CPtr;
/* newC1 *****************************************************************/
extern CPtr newC1(void);
/* Pre:
Modifies:
Post: Return a new C1 instance.
*/
/* newC2 *****************************************************************/
extern CPtr newC2(void);
/* Pre:
Modifies:
Post: Return a new C2 instance.
*/
/* destroy ***************************************************************/
extern void destroy(CPtr *cp);
/* Pre: Assigned(cp)
Modifies: cp
Post: Delete cp.
*/
/* className *************************************************************/
extern const char *className(CPtr cp);
/* Pre: Assigned(cp)
Modifies:
Post: Return the class name of cp.
*/
/* f *********************************************************************/
extern void f(CPtr);
/* Pre: Assigned(cp)
Modifies:
Post: Send cp->f()
*/
/* g *********************************************************************/
extern void g(CPtr);
/* Pre: Assigned(cp)
Modifies:
Post: Send cp->g()
*/
#if defined( __cplusplus )
#endif // __WRAPPER_H
/* end of wrapper.h ******************************************************/
End of wrapper.h
echo test.c 1>&2
cat >test.c <<'End of test.c'
/* test.c -- Test program for C++ wrappers for C
* (c) 1994, by Kevin Walker
*/
#include <stdio.h>
#include "wrapper.h" /* C++ wrapper definitions */
main()
{
CPtr p1 = newC1(), /* Create a C1 instance */
p2 = newC2(); /* Create a C2 instance */
/* Try the className() method */
printf("%s\n", className(p1));
printf("%s\n", className(p2));
/* Try the f() method */
f(p1);
f(p2);
/* Try the g() method */
g(p1);
g(p2);
/* Call destructors */
destroy(&p1);
destroy(&p2);
return 0;
echo wrapper.cc 1>&2
cat >wrapper.cc <<'End of wrapper.cc'
// wrapper.cc -- C wrappers for C++ class methods
// (c) 1994 WHC
// Version: 12/08/94
// NOTE: All of these functions simply type-cast the CPtr type to a
// pointer to a class C and call a class C method.
// include files **********************************************************
#include "wrapper.h"
#include "C.h"
#include "C1.h"
#include "C2.h"
// Use "C" linkage
extern "C" {
// newC1 ******************************************************************
CPtr newC1(void)
// Pre:
// Modifies:
// Post: Return a new C1 instance.
{
return (CPtr) new C1;
CPtr newC2(void)
// Pre:
// Modifies:
// Post: Return a new C2 instance.
{
return (CPtr) new C2;
void destroy(CPtr *cp)
// Pre: Assigned(cp)
// Modifies: cp
// Post: Delete cp.
{
delete ((C *) *cp);
*cp = 0;
const char *className(CPtr cp)
// Pre: Assigned(cp)
// Modifies:
// Post: Return the class name of cp.
{
return ((C *) cp)->className();
void f(CPtr cp)
// Pre: Assigned(cp)
// Modifies:
// Post: Send cp->f()
{
((C *) cp)->f();
void g(CPtr cp)
// Pre: Assigned(cp)
// Modifies:
// Post: Send cp->g()
{
((C *) cp)->g();
} // extern "C"
End of wrapper.cc
echo makefile 1>&2
cat >makefile <<'End of makefile'
# makefile for C++ wrapper example
# by Kevin Walker -- kgw...@fep1.rl.gov
CFLAGS=-g -c
CC=CC
# Note: I'm using $(CC) here because it works. Actually. the "C"
# compiler cc should be used eventually.
test : test.o wrapper.o
$(CC) test.o wrapper.o -o test
test.o : test.c
cc $(CFLAGS) test.c
wrapper.o : wrapper.cc
$(CC) $(CFLAGS) wrapper.cc
clean :
rm *.o
End of makefile
echo README 1>&2
cat >README <<'End of README'
From: Kevin Walker -- kgw...@fep1.rl.gov
Subject: C wrappers for C++
I found a method for using C++ code in C programs in the SPARCompiler
C++ 4.0 user's guide. This is supposed to allow you to write C routines
that operate on C++ classes such that you can use the classes in a C
program. I wrote a small example to try it out but it won't link properly.
The idea is to use C linkage to create C compatible object files. The
following files are included:
C.h -- an abstract C++ base class
C1.h -- a derived class
C2.h -- another derived class
wrapper.h -- declarations of wrapper type and functions
wrapper.cc -- implementation of wrapper functions
test.c -- test of wrapper functions
makefile
The line in the makefile to create the executable should be changed to use
the C compiler. As of now, only the C++ compiler will work. If anyone knows
how to fix this, tell me.
Kevin Walker -- kgw...@fep1.rl.gov
End of README
===========================end share file==============================