Re: linking C++ functions in a C program



CBFalconer wrote:
James Kuyper wrote:
CBFalconer wrote: Various incorrect things.

... snip ...
Rather than repeat my previous failed attempts to get a straight
answer out of you about that question, I've written a program that
contains one function named foo() which is compiled in C, and is
therefore unambiguously a C function. It contains another function
named baz() compiled in C++ that has "C++" language linkage, so it
is unambiguously a C++ function. foo() calls bar() which calls
baz(). Therefore, no matter how you classify bar(), this program
contains a C function calling a C++ function.

foobar.h:
========================
#ifndef FOOBAR_H
#define FOOBAR_H

#ifdef __cplusplus
extern "C" {
#endif

void foo(int);
void bar(int);

#ifdef __cplusplus
}
#endif
#endif

foo.c:
===================================
#include <stdio.h>
#include "foobar.h"

void foo(int i) {
puts("About to call bar()");
bar(i);
puts("Finished calling bar()");
}

main.C
==================================================
#include <iostream>
#include "foobar.h"

int main() {
foo(42);
}

static void baz(int i) {
std::cout << "the number is:" << i << std::endl;
}

void bar(int i) {
baz(i);
}

I concede my posts have not been accurate. I still don't think C
calling C++ is convenient, accurate, and really useful, although
possible. In the above:

It's sometimes inconvenient, since you lose certain benefits of C++ and have to add some extra syntactic sugar when you make a function callable from C. However, it is quite certainly "accurate" and "useful".

I've worked with several libraries that used C++ internally and provided both a C interface and a C++ interface; the C interface was simply a bunch of wrapper functions that manipulated the C++ interface, which a C program couldn't see (because it used classes).

foobar.h sets up definitions of foo and bar that requires them to
be called without name adornment The actual code is implemented in
the C++ file (.cpp would be more descriptive than .C, IMO).

..cpp or .cc is the usual convention when there's any possibility of confusion. The .C convention doesn't work on systems that aren't case-sensitive (e.g. Windows).

I guess the compiler can generate two references to foo, one adorned,
and one not adorned, although that is an unnecessary complication.

That's not required.

The C compiler processing foo.c will see a normal C function named foo(), and it will generate the object code as it always does.

The C++ compiler processing main.C will see an extern "C" function named foo(), and any time that C++ code calls it, it will call the unmangled C name instead of the default mangled C++ name.

Since the C++ code is calling the unmangled name foo(), and the C compiler produced a function named foo(), everything works.

Some confusion: Note that the code for bar is compiled with a C++
compiler. Thus it must follow C++ rules, for such things as
reserved names, size of char constants, etc. It can thus make a
great difference if bar is moved to a .c file, #includes
"foobar.h", and totally removed from main.C. To me, this is a
cleaner organization, and ensures that C code is compiled as C, and
C++ code is compiled as C++. Conceded, it will prevent using
std::cout etc.

bar() and baz() are both C++ functions, and are properly compiled with a C++ compiler. bar() is callable from C, due to the way it's declared, but baz() is not. However, bar() can call baz(), which makes bar() a "wrapper" function for baz().

The wrapper is unnecessary in this case (baz() could have been extern "C" and called directly from foo(), since its declaration doesn't require any special C++ features), but it's a useful technique at times.

S
.



Relevant Pages

  • Re: fields for methods?
    ... but only by a compiler that is allowed to ... struct A {void foo();}; ... int static_instance i = 0; ... Is not possible because foo is the only member of A... ...
    (comp.programming)
  • Re: linking C++ functions in a C program
    ... contains one function named foo() which is compiled in C, ... Therefore, no matter how you classify bar(), this program ... void foo; ... guess the compiler can generate two references to foo, one adorned, ...
    (comp.lang.c)
  • Re: Sharing a struct between threads?
    ... struct in my mainbut cant seem to access the struct in the thread ... A C compiler must see the ... Do you think a compiler is going to look at this and say "maybe 'foo' ... 'foo' up to the 'j' in bar?" ...
    (comp.unix.programmer)
  • Re: [C] return statement in void function?
    ... struct foo copy{ ... compiler really does have to think about. ... T foo (U fxn) ... > evaluates to void. ...
    (alt.comp.lang.learn.c-cpp)
  • Circular dependency - I think..
    ... The header file for FOO is composed of BAR, ... int GetFbk(); ... void ComputeTorquerCmd(); ...
    (comp.lang.cpp)

Loading