Help linking c++ code with c

Help linking c++ code with c

Post by Donald M. Bro » Thu, 22 Dec 1994 02:22:49



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:

> % make
> 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'

Please email any replies to me and I'll see that they are forwarded
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;

};

#endif   // __C_H

// 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; }

};

#endif   // __C1_H

// 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; }

};

#endif   // __C2_H

// 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

#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;

}

End of test.c
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;

}

// newC2 ******************************************************************

CPtr newC2(void)
// Pre:
// Modifies:
// Post: Return a new C2 instance.
{
   return (CPtr) new C2;

}

// destroy ****************************************************************

void destroy(CPtr *cp)
// Pre: Assigned(cp)
// Modifies: cp
// Post: Delete cp.
{
   delete ((C *) *cp);
   *cp = 0;

}

// className **************************************************************

const char *className(CPtr cp)
// Pre: Assigned(cp)
// Modifies:
// Post: Return the class name of cp.
{
   return ((C *) cp)->className();

}

// f **********************************************************************

void f(CPtr cp)
// Pre: Assigned(cp)
// Modifies:
// Post: Send cp->f()
{
   ((C *) cp)->f();

}

// g **********************************************************************

void g(CPtr cp)
// Pre: Assigned(cp)
// Modifies:
// Post: Send cp->g()
{
   ((C *) cp)->g();

}
}  // extern "C"

// end of wrapper.cc ******************************************************
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==============================

 
 
 

Help linking c++ code with c

Post by Douglas Zimmerm » Fri, 23 Dec 1994 05:27:22



|> 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.

The first thing you need to do is use the C++ compiler to do your
linking, or possibly add the C++ runtime library in the link.
Your example totally failed to link to the C++ runtime library,
which explains all your undefined references.

There is also a chance you may have the same problem I had with the HP
C++ compiler.  In that case, main() needed to be compiled with C++, in
order to get the iostream initialization correct.  In that case, there
was no link problem, but using iostreams failed at runtime.  This was
evidently due to the use of cfront doing special initializations around
main() to convert a C main into a C++ main.  Other C++ compiler not
built using cfront (g++, and the Microsoft and Borland compilers on the
PC) do not have this problem, as the C++ library does the
initializations properly even if main was written in C.

 
 
 

Help linking c++ code with c

Post by Jean-Alexis_Berrang » Sat, 24 Dec 1994 02:50:04



Quote:> 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:

> > % make
> > 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'

Why not compile everything with CC ??

my $0.02

 
 
 

Help linking c++ code with c

Post by Erik Cornils » Mon, 26 Dec 1994 02:00:45




>> 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:

>> > % make
>> > 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'
>Why not compile everything with CC ??
>my $0.02

  I did this just the other day.  In the C++ files, anything you want to use
in a C source file you must precede with  'extern "C"'.  This, as I understand
it, defeats name-mangling needed for overloading and argument type checking.
C doesn't know how to do that anyway, so you don't loose anything.  You can
still overload functions in your C++ code, but only one of the functions will
be available to the C code.  What I would do, and this isn't a very informed
opinion, is put the function declarations I want to use in my C code in a
header file.  The C++ source should use 'extern "C" {#include <cfuncs.h>}'.  I
think that should work.  You can use this same method to use C functions in
your C++ code.
--
---------------------------------
University of Colorado at Boulder

 
 
 

Help linking c++ code with c

Post by Terrell Tuck » Wed, 04 Jan 1995 14:43:55


Yes, after a good deal of agony I discovered this works for me too in
MSVC.  My C++ functions in my .cpp file must all have  extern "C"  in front.
However the headers in the .h file must not have the extern "C".  

Moreover I must not include the .h file above the .cpp file itself, only the
other .c files that want to call the functions get the .h file.  Messy.

--

 
 
 

Help linking c++ code with c

Post by Nam c. L » Thu, 05 Jan 1995 23:51:34


: Yes, after a good deal of agony I discovered this works for me too in
: MSVC.  My C++ functions in my .cpp file must all have  extern "C"  in front.
: However the headers in the .h file must not have the extern "C".  

: Moreover I must not include the .h file above the .cpp file itself, only
the
: other .c files that want to call the functions get the .h file.  Messy.

: --
Thnaks for the info provided by this news topic.
Question: Is there any doc that categorizes all these PROCEDURAL CONSTRIANTS
          (Or Mess of reality)?

The GAP between c and c++ is quite wide indeed! Isn't it?

--
Nam c. Low              Networks Control Logistics
P.Eng,Ph.D              PC Internetworks Training & Consulting
                        Scarborough, Ontario, Canada
--------------------------------------------------------------

 
 
 

Help linking c++ code with c

Post by Tim Frie » Fri, 06 Jan 1995 01:59:17


Newsgroups: comp.unix.programmer,comp.lang.c++,comp.lang.c


Distribution: world
Followup-To:

Organization: Command Tactical Information System, United States Air Force
Keywords: bindings

|> Yes, after a good deal of agony I discovered this works for me too in
|> MSVC.  My C++ functions in my .cpp file must all have  extern "C"  in front.
|> However the headers in the .h file must not have the extern "C".  
|>
|> Moreover I must not include the .h file above the .cpp file itself, only the
|> other .c files that want to call the functions get the .h file.  Messy.
|>
|> --
We have #ifdef __cplusplus around our extern "C" { so that the C code doesn't
see it and complain...

We put the extern C around the prototypes, and not around the functions....

This works fine with G++/GCC and Lucid's LCC

 
 
 

Help linking c++ code with c

Post by Tim Frie » Thu, 05 Jan 1995 23:36:47


Newsgroups: comp.unix.programmer,comp.lang.c++,comp.lang.c


Distribution: world
Followup-To:

Organization: Command Tactical Information System, United States Air Force
Keywords: bindings

|> Yes, after a good deal of agony I discovered this works for me too in
|> MSVC.  My C++ functions in my .cpp file must all have  extern "C"  in front.
|> However the headers in the .h file must not have the extern "C".  
|>
|> Moreover I must not include the .h file above the .cpp file itself, only the
|> other .c files that want to call the functions get the .h file.  Messy.
|>
|> --
We have #ifdef __cplusplus around our extern "C" { so that the C code doesn't
see it and complain...

We put the extern C around the prototypes, and not around the functions....

This works fine with G++/GCC and Lucid's LCC

 
 
 

1. Linking C code with C++ code

Hi,

Let me describe a challenging problem for me. I have some old c code
which has some functionality I need to keep as is and some C++ code I
also need to leave as is. I need to create a link between the c code and
C++ code.

So, I just made a new .h and .cpp file which defines the interface
functions to the C++ functions. Compiled the new .cpp to a .o file. Now,
I did a #include of my new .h file in one of the old c code .c files.
Since the new .h was included, I used the functions in a few places of
the old c code.

Then I added to the (old c code) makefile the additonal .o (from the new
cpp) for linking, added the new .h also to the (old c code) makefile,
and Shezzaam, I thought the two would be linked. Nope. Oh, I have WATCOM
C and C++ on QNX 4.2, a POSIX compliant varient of UNIX.

The linker says the function names in the new .h file are unreferenced,
undefined when
trying to compile the old c code. Since the .h has the prototypes of the
new functions, I am
confused. I did found from the disassembler (wdisasm) that the 'c'
compiler (wcc386) appended an ' _ ' (underscore) to every function name
we had added to the old c code.

Since the #included .h did not have ' _ ' (underscore) on the function
names, I thought that was the problem. Using a preprocessor directive
(#pragma aux's), I forced the 'c' compiler NOT to
append the ' _ ' to the new function names in the .o file.

But, no luck. the 'c' compiler still says Warning(1028): blah, blah is an
unreferenced name and then the fatal Error messages saying blah, blah is
an undefined name.

So, how do I get my 'c' compiler to link in the new .o file in?

Michael R.

2. RedHat 4.0 can use dip...

3. Help - want C++ generic linked-list class code

4. .FVWM2-errors found after running XFree86 under Redhat 5.2

5. Help Link C/C++ code

6. Problems installing on Future Domain SCSI

7. linking C++ code to a shared object on AIX

8. Apache 1.3.0 webserver not responding.

9. SunSoft f77 -autopar linked with C++ code

10. HOW CAN I LINK libg++ LIBRARY TO COMPILE C++ CODES UNDER GCC?

11. Linking C Code with C++ Libraries

12. Linking C++ and Fortran code???