public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* RE: Help : Linking C and C++ code
       [not found] <000d01c169b4$4f891c20$8200a8c0@ferrum>
@ 2001-11-01  3:13 ` Rupert Wood
  0 siblings, 0 replies; only message in thread
From: Rupert Wood @ 2001-11-01  3:13 UTC (permalink / raw)
  To: 'Ujval Lodha'; +Cc: gcc-help

Ujval Lodha wrote:

> I am trying to link some C code with C++ code. The compiler returns
> with =93undefined reference to <function>=94 for the function
> written in the C++ file.
> 
> Please advise on how to call a C++ function from a C program and
> link the two.

In C++, it is valid to have two functions with the same name but
different arguments, e.g.

	int   foo(int);
	char* foo(char*);

and the compiler decides which one to call based on context. However,
the two functions need to be exported with different symbols. Hence C++
'mangles' or 'decorates' the name, adding extra characters to represent
the represent the call parameters (and, where appropriate, namespace,
class, constness, etc.) For example, on my system, the above functions
are exported with names:

	int   foo(int);      => _Z3fooi
	char* foo(char*);    => _Z3fooPc

Now the problem is that C assumes that symbol names are prefixed with an
underscore (or unchanged - system dependently) and so it can't match the
mangled names. Whilst you could get your C code to call 'Z3fooi'
instead, this probably isn't safe; firstly, the mangled form is compiler
specific and secondly it might not be safe to assume that the C++ code
has the same ABI (Application Binary Interface?) as the C code. Hence
you should export the C++ function as 'extern "C"'; e.g. either of:

      extern "C" int foo(int);
      int foo(int a) { return a + 1; }
or

      extern "C" int foo(int a) { return a + 1; }

However, this will only work for plain functions; if you need C++
mangled names (e.g. a class static function) then you should create an
extern "C" wrapper function, e.g.:

      class bar {
          public:
              static int foo(int);
      };
      int bar::foo(int a) { return a + 1; }
      extern "C" int C_foo(int a) { return bar::foo(a); }

which you can call from your C code as normal.

If you need a combined C/C++ header, you can wrap the 'extern "C"' in
#ifdef __cplusplus

    #ifdef __cplusplus
    extern "C" {
    #endif

    int foo(int);

    #ifdef __cplusplus
    }
    #endif

Good luck,
Rup.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2001-11-12  7:20 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <000d01c169b4$4f891c20$8200a8c0@ferrum>
2001-11-01  3:13 ` Help : Linking C and C++ code Rupert Wood

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).