Topic: Calling C++ functions from C


Author: nevries@cs.ruu.nl (Nico de Vries)
Date: 17 Sep 91 10:11:42 GMT
Raw View
In <1991Sep13.191134.25395@saifr00.cfsat.honeywell.com> josh@saifr00.cfsat.honeywell.com (Josh Lam) writes:

>...
>I need help on how to call C++ functions from C.
>...

C++ is an "enhanced" version of C. Calling C from C++ is no problem
(extern "C") but the other way arround can be verry difficult.
C++ supports type safe linking which means the name of a function
is expanded with type information (most compilers include invisible pre
and postfixes). This means the C and the C++ names of a function are
different for the linker. If you have detailed information about
how name mangling/demangling is done in your C++ compiler you
could try to emulate it by hand. Perhaps your compiler supports
C and C++ and some switch or enhancement does the trick.


Nico de Vries




Author: cimshop!davidm@uunet.UU.NET (David S. Masterson)
Date: 17 Sep 91 19:34:36 GMT
Raw View
>>>>> On 17 Sep 91 10:11:42 GMT, nevries@cs.ruu.nl (Nico de Vries) said:

Nico> In <1991Sep13.191134.25395@saifr00.cfsat.honeywell.com>
Nico> josh@saifr00.cfsat.honeywell.com (Josh Lam) writes:

Josh> ...
Josh> I need help on how to call C++ functions from C.
Josh> ...

Nico> C++ is an "enhanced" version of C. Calling C from C++ is no problem
Nico> (extern "C") but the other way arround can be verry difficult.  C++
Nico> supports type safe linking which means the name of a function is
Nico> expanded with type information (most compilers include invisible pre and
Nico> postfixes). This means the C and the C++ names of a function are
Nico> different for the linker. If you have detailed information about how
Nico> name mangling/demangling is done in your C++ compiler you could try to
Nico> emulate it by hand. Perhaps your compiler supports C and C++ and some
Nico> switch or enhancement does the trick.

No trick required, although the way to do it looks like a trick!  The method
is to use extern "C" (ta da!).  For instance, the following code will work:

// **************
#include <iostream.h>

class alpha {
 int x;
public:
 alpha(int a) : x(a) {}
 friend ostream& operator<<(ostream& s, alpha& a)
  { return s << "x = " << a.x; }
};

extern "C" {
 void testfunc() { alpha x(1); cout << x << endl; }
}

int main() {
 testfunc(); // could call other C||C++ functions
   // which eventually calls testfunc()
}

// *****************

The key thing to note is that most C++ compilers do some initialization in the
main routine.  Therefore, it is very unlikely that you could make the main
routine a C function and still have it work well with C++ functions.
--
====================================================================
David Masterson     Consilium, Inc.
(415) 691-6311     640 Clyde Ct.
uunet!cimshop!davidm    Mtn. View, CA  94043
====================================================================
"If someone thinks they know what I said, then I didn't say it!"




Author: glenn@bitstream.com (Glenn P. Parker)
Date: 17 Sep 91 14:26:02 GMT
Raw View
[Followups to comp.lang.c++,comp.lang.c]

In article <1991Sep17.101142.3205@cs.ruu.nl> nevries@cs.ruu.nl (Nico de Vries) writes:
> In <1991Sep13.191134.25395@saifr00.cfsat.honeywell.com> josh@saifr00.cfsat.honeywell.com (Josh Lam) writes:
>
> >...
> >I need help on how to call C++ functions from C.
> >...
>
> C++ is an "enhanced" version of C. Calling C from C++ is no problem
> (extern "C") but the other way arround can be verry difficult.
> ...

Fooey!

If you are willing to define your "main()" in a C++ file and perform your
final link using a C++ linker, then the following should be a very portable
example of calling C++ from C.  All you need is some "glue" functions that
your C code can call.  Declare one or more C++ functions with "C" linkage
which in turn call your C++ functions, like so:

--foo.h--

    /* A C or C++ header file. */
    #ifdef __cplusplus

    class Some {
      public:
 Some();
 ~Some();
 void Thing(int arg1, int arg2);
 int A();

      private:
 int a;
    };

    typedef Some* SomeP;
    #define C_LINKAGE extern "C"

    #else

    typedef void* SomeP;
    #define C_LINKAGE extern

    #endif

    C_LINKAGE SomeP some_new();
    C_LINKAGE void some_delete(SomeP);
    C_LINKAGE void some_thing(SomeP, int arg1, int arg2);
    C_LINKAGE int some_a(SomeP);

--foo.C--

    /* A C++ file. */
    #include "foo.h"
    extern "C" void bar();

    Some::Some() : a(0) {}
    Some::~Some() {}
    void Some::Thing(int arg1, int arg2) { a = arg1 + arg2; }
    int Some::A() { return a; }
    C_LINKAGE SomeP some_new() { return new Some; }
    C_LINKAGE void some_delete(SomeP some) { delete some; }
    C_LINKAGE void some_thing(SomeP some, int arg1, int arg2)
    { some->Thing(arg1, arg2); }
    C_LINKAGE int some_a(SomeP some) { return some->A(); }

    main()
    {
 bar();
    }

--bar.c--

    /* A C file. */
    #include "foo.h"

    void bar()
    {
 int x;
 SomeP some = some_new();
 some_thing(some, 1, 2);
 x = some_a(some);
 some_delete(some);
    }

--
Glenn P. Parker       glenn@bitstream.com       Bitstream, Inc.
                      uunet!huxley!glenn        215 First Street
                      BIX: parker               Cambridge, MA 02142-1270




Author: steve@taumet.com (Stephen D. Clamage)
Date: 17 Sep 91 16:06:08 GMT
Raw View
nevries@cs.ruu.nl (Nico de Vries) writes:

>>I need help on how to call C++ functions from C.

>C++ is an "enhanced" version of C. Calling C from C++ is no problem
>(extern "C") but the other way arround can be verry difficult.

This is not correct.  Using `extern "C"' on the C++ function ensures
it may be called in the ordinary way by a C function.  You do have
to watch out for features specific to C++, however.  Class member
functions can not be directly called from C (portably), and class
definitions can not be converted to C (portably).

To take a trivial example, suppose we have a cube-root function
written and compiled in C++:
 extern "C" double cube_root(double x) { ... }

We are guaranteed that the following C code fragment will work:
 double cube_root(double);
 foo(double x) { ... cube_root(x) ... }
--

Steve Clamage, TauMetric Corp, steve@taumet.com




Author: pena@brainware.fi (Olli-Matti Penttinen)
Date: 17 Sep 91 18:48:55 GMT
Raw View
In article <952@taumet.com> steve@taumet.com (Stephen D. Clamage) writes:

   To take a trivial example, suppose we have a cube-root function
   written and compiled in C++:
    extern "C" double cube_root(double x) { ... }

   We are guaranteed that the following C code fragment will work:
    double cube_root(double);
    foo(double x) { ... cube_root(x) ... }

EXCEPT for the case in which a C compiler is used to compile main()
and/or a non-C++-aware linker is used and any compilation unit that
cube_root relies on has defined static objects that need non-trivial
initialization (ie. a constructor must be called).

That situation may arise if one wants to write a library in C++ for
both C++ and C users. If the API to the library is not fixed or has an
entry point for initialization, one could construct the library
objects in the initialization code if their state is undefined.
Naturally, the same applies to finalization (calling destructors), as
well.

==pena
--
Olli-Matti Penttinen <pena@brainware.fi> | "When in doubt, use brute force."
Brainware Oy                             |    --Ken Thompson
P.O.Box 330                              +----------------------------------
02151  ESPOO, Finland       Tel. +358 0 4354 2565       Fax. +358 0 461 617




Author: nevries@cs.ruu.nl (Nico de Vries)
Date: 23 Sep 91 09:45:09 GMT
Raw View
Some days ago I wrote calling C++ from C would mean demangling
names by hand. I noticed in the mean time the extern "C" can be used
for defining C compatible functions as well. But this still leaves
some problems:
- when using a true C linker it is possible the C++ names are too
  long for the linker.
- many C++ features (construction detruction etc) are not
  supported by non C++ environments

As I mentioned before, if the C compiler is part of a C/C++ package
there are probably extentions allowing C++ to be called from C.
For a pure C environment to call C++ functions from another
compiler (the origional question to which I responded) I still
see considerable problems.

Has anyone TRUE experience with this problem?

Nico de Vries




Author: cimshop!davidm@uunet.UU.NET (David S. Masterson)
Date: 23 Sep 91 17:23:00 GMT
Raw View
>>>>> On 23 Sep 91 09:45:09 GMT, nevries@cs.ruu.nl (Nico de Vries) said:

Nico> As I mentioned before, if the C compiler is part of a C/C++ package
Nico> there are probably extentions allowing C++ to be called from C.
Nico> For a pure C environment to call C++ functions from another
Nico> compiler (the origional question to which I responded) I still
Nico> see considerable problems.

Nico> Has anyone TRUE experience with this problem?

Are you saying that you have a library of compiled C++ objects and no C++
compiler to use them with?  If so, how do plan to use the header files that
are associated with the objects?  Is getting a C++ compiler out of the
question?

C++ is largely backward compatible with C, but nothing has ever been said
about making C forward compatible with C++.  Until that forward compatibility
is there, though, any solution to the above is just an implementation hack
and, therefore, non-portable.  An analogy would be how would you call
Assembler routines from C if the Assembler routines had not been written with
a C compiler in mind (pushing and popping from the stack in the right order)?
--
====================================================================
David Masterson     Consilium, Inc.
(415) 691-6311     640 Clyde Ct.
uunet!cimshop!davidm    Mtn. View, CA  94043
====================================================================
"If someone thinks they know what I said, then I didn't say it!"




Author: nevries@cs.ruu.nl (Nico de Vries)
Date: 26 Sep 91 10:13:01 GMT
Raw View
I don't have the problem of calling C++ from pure C
myself. Someone else posted the problem and I just
responded.

Nico de Vries




Author: cimshop!davidm@uunet.UU.NET (David S. Masterson)
Date: 28 Sep 91 01:30:45 GMT
Raw View
>>>>> On 26 Sep 91 10:13:01 GMT, nevries@cs.ruu.nl (Nico de Vries) said:

Nico> I don't have the problem of calling C++ from pure C myself. Someone else
Nico> posted the problem and I just responded.

My points are still valid, though.  Attempting to use C++ code without a C++
compiler would have to be very problematical at best.  It is most likely less
of a problem to go out and buy a C++ compiler for an environment than it is to
attempt to use compiled C++ code from a C environment.  Even if one doesn't
have the source code to the implementation of the objects in the C++ library,
the C++ headers should still be available (if not, boy...).  With the C++
compiler and the headers, there should be no problems interfacing non-C++ code
to the C++ library.
--
====================================================================
David Masterson     Consilium, Inc.
(415) 691-6311     640 Clyde Ct.
uunet!cimshop!davidm    Mtn. View, CA  94043
====================================================================
"If someone thinks they know what I said, then I didn't say it!"




Author: josh@saifr00.cfsat.honeywell.com (Josh Lam)
Date: 13 Sep 91 19:11:34 GMT
Raw View
Hi,

I need help on how to call C++ functions from C.

I am currently working on a Sun Unix environment.  I have some C++
functions already available.  How can I write a C program to call these C++
functions (I will be compiling the C program with a C compiler).

Would really appreciate some help!

Thanks!

Josh