linking C++ functions in a C program

A

abasili

Hi everyone, I'm trying to compile a C++ function and then call it from
a C program.
Since Google is my friend I've ended up to this link which seems very clear:

http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html

Unfortunately it does not work.
Here is what I'm doing:

-----------------------------------------
//main.c

#include "mylib.h"

int main (int argc, char *argv[]){
foo();
return 0;
}
-----------------------------------------
//mylib.h

#indef __cplusplus
extern "C"{
#endif

void foo();

#ifdef __cplusplus
}
#endif
-----------------------------------------
//mylib.cc

#include <iostream>
#include "mylib.h"

using namespace std; // don't know what for!

void foo(){
cout<<"Hello World!\n";
}
-----------------------------------------


Thanks a lot for any suggestion.

Al
 
I

Ian Collins

abasili said:
Hi everyone, I'm trying to compile a C++ function and then call it from
a C program.
Since Google is my friend I've ended up to this link which seems very
clear:

http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html

Unfortunately it does not work.

It does if you follow all the points. The first two are often overlooked.
Here is what I'm doing:

-----------------------------------------
//main.c

#include "mylib.h"

int main (int argc, char *argv[]){
foo();
return 0;
}

How are you building your executable?
 
A

abasili

Ian said:
It does if you follow all the points. The first two are often overlooked.

Here is my Makefile
How are you building your executable?


Here is my Makefile
-----------------------------------------

OS = OS_LINUX
CC = gcc
CXX = g++
AR = ar

INCMYLIB = mylib.h

INC = $(INCMYLIB)

OBJMYLIB = mylib.o

OBJ = $(OBJMYLIB)

ROOTINCL = $(ROOTSYS)/include

MYLIB = mylib.a

CFLAGS = -g -D$(OS) -Wall -O2 -fno-strict-aliasing \
-I/usr/X11R6/include/ -I/usr/X11R6/include/X11
-I$(ROOTINCL) \

BOOLFLAG = -D_BOOL
ROOTFLAG = `root-config --libs`
CCFLAG = $(BOOLFLAG) $(ROOTFLAG)

LDFLAGS = -L/usr/X11R6/lib -z muldefs
LOADMYLIBES = $(MYLIB) -lm -lX11 -Xlinker -Bstatic -lforms -Xlinker
-Bdynamic

INT = main

EXT =

EXE = $(EXT) $(INT)
#------------------------------------------------------------------------------

all: $(OBJ) $(MYLIB) $(EXE)

#------------------------------------------------------------------------------

%.o: %.c $(INC)
$(CC) -c -o $*.o $*.c $(CFLAGS)

%.o: %.cc $(INC)
$(CXX) -c -o $*.o $*.cc $(CFLAGS) $(BOOLFLAG)

$(MYLIB): $(OBJ)
$(AR) cru $(MYLIB) $(OBJ)

%: %.c $(MYLIB)
$(CC) -o $* $*.c $(CFLAGS) $(LDFLAGS) $(LOADMYLIBES)

%: %.cc $(MYLIB)
$(CXX) -o $* $*.cc $(CFLAGS) $(CCFLAG) $(LDFLAGS) $(LOADMYLIBES)

#------------------------------------------------------------------------------
export:
cp -p -f $(EXT) /usr/local/bin

#------------------------------------------------------------------------------

clean:
rm -f *~ *.bak *.o $(EXE) core

#==============================================================================


This Makefile is used to compile several programs and be able to use
somebody else library, here I reduced it to the minimum only to study
this case.
Thanks,

Al
 
A

abasili

Ian said:
It does if you follow all the points. The first two are often overlooked.
I'm sorry about that, actually compiling with g++ the main works.
The main problem is that my C program cannot be compiled with g++, there
are too many incompatibilities and a lot of work has been already done in C.
So I have to find another way to call a C++ function through my C code.
 
A

abasili

abasili said:
So I have to find another way to call a C++ function through my C code.

Problem is solved.
I created a new main.cc which will call my main_C.c which will be
compiled with gcc, while the main.cc is compiled with g++.
It's rather tricky but it works.
If anyone else have a different idea i'll be happy to change my approach.
Cheers,

Al
 
J

James Kuyper

abasili said:
Here is my Makefile


Here is my Makefile

As Ian said, the first two points are often overlooked, and your
makefile has violated both of them. You compile main() with C instead of
C++, and you use the C compiler rather than the C++ compiler to link the
modules together.

Note: it would have been better to post this message to comp.lang.c++.
The ability to link C code with C++ is defined as part of the C++
standard. The C standard says nothing about that capability. You'll find
more people in that group who can help you than you can find in this group.
 
J

James Kuyper

abasili wrote:
....
#indef __cplusplus

That should be #ifdef
//mylib.cc

#include <iostream>
#include "mylib.h"

using namespace std; // don't know what for!

For cout, of course. Without that using statement, you'd have to refer
to std::cout.
 
C

CBFalconer

abasili said:
I'm sorry about that, actually compiling with g++ the main works.
The main problem is that my C program cannot be compiled with g++,
there are too many incompatibilities and a lot of work has been
already done in C. So I have to find another way to call a C++
function through my C code.

In general, you just can't do that. C++ function names are
normally altered by the C++ compiler for various reasons. C
function names are not. So the C system can't link the C++ code.
 
J

jameskuyper

CBFalconer said:
In general, you just can't do that. C++ function names are
normally altered by the C++ compiler for various reasons.

True, but extern "C" turns that off. The only part of his program
compiled with the C++ compiler is a function declared with extern "C".
C
function names are not. So the C system can't link the C++ code.

That may be true; but not for the reason given.
 
P

Pawel Dziepak

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
In general, you just can't do that. C++ function names are
normally altered by the C++ compiler for various reasons. C
function names are not. So the C system can't link the C++ code.

7.5/3 states that: "Every implementation shall provide for linkage to
functions written in the C programming language" by allowing things like
extern "C"
7.5/6 tells us that is is possible to define function with C-style
linkage in C++ code.
7.5/9 informs us that implementation can allow to link objects from
other languages to C++ and from C++ to other languages.

Concluding, C++ standard gives possibility to link C++ functions from C
code (with some naming restrictions).

Pawel Dziepak
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkkTLUIACgkQPFW+cUiIHNrXWwCfaS8A41lRmL6kpsneGgyHLEBt
qdEAoJCroT5PWNIluUsCyyfE1IQUorPo
=R7xw
-----END PGP SIGNATURE-----
 
S

Stephen Sprunk

abasili said:
I'm sorry about that, actually compiling with g++ the main works.
The main problem is that my C program cannot be compiled with g++, there
are too many incompatibilities and a lot of work has been already done
in C.
So I have to find another way to call a C++ function through my C code.

Always compile C++ source files with a C++ compiler.
Always compile C source files with a C compiler.
If you have a mix of object files from the two languages, use the C++
compiler's linker.

Problem solved.

S
 
K

Keith Thompson

CBFalconer said:
In general, you just can't do that. C++ function names are
normally altered by the C++ compiler for various reasons. C
function names are not. So the C system can't link the C++ code.

Chuck, we've had this discussion before. Yes, you can call C++
functions from C, and yes, you can call C functions from C++. C++
defines the mechanism for doing this in both directions.

Last time we discussed this, I pointed you to the C++ FAQ that
explains this; it's already been cited in this thread. I even
demonstrated how to do it and posted the output. For some reason you
still didn't believe me, and now you're claiming yet again that it
can't be done.

Please consider the possibility that you might be wrong.
 
C

CBFalconer

jameskuyper said:
CBFalconer wrote:
.... snip ...


True, but extern "C" turns that off. The only part of his program
compiled with the C++ compiler is a function declared with extern
"C".

They are not compiled with the C++ compiler, they should be
compiled with the C compiler. The object code may be linked with
the C++ linker. The <extern "C"> term is only in the .h file that
describes the access to the C code required. In general C++ can
access C code, but C cannot access C++ code.

Remember, the languages are different.
 
C

CBFalconer

Pawel said:
7.5/3 states that: "Every implementation shall provide for linkage
to functions written in the C programming language" by allowing
things like extern "C"
7.5/6 tells us that is is possible to define function with C-style
linkage in C++ code.
7.5/9 informs us that implementation can allow to link objects from
other languages to C++ and from C++ to other languages.

Concluding, C++ standard gives possibility to link C++ functions
from C code (with some naming restrictions).

You are quoting from, I believe, the C++ standard. My point is
that C cannot call to C++ code, but C++ can call C code. The idea
is to prepare C object code and allow the C++ system to call it
correctly, by using the extern "C" identification _in the header
file for the C code_.

The C++ standard is meaningless in c.l.c. Here, we use the C std.
 
F

Flash Gordon

CBFalconer wrote, On 06/11/08 21:54:

describes the access to the C code required. In general C++ can
access C code, but C cannot access C++ code.

Remember, the languages are different.

Remember, it has been pointed out to you many times and with references
that you are WRONG. C++ defines how C code can call C++ code and you
have been shown how it works. Since the theory says it should work and
practice shows that it works why keep insisting that it does not?
Neither theory nor practice are on your side.
 
C

CBFalconer

Keith said:
.... snip ...


Chuck, we've had this discussion before. Yes, you can call C++
functions from C, and yes, you can call C functions from C++. C++
defines the mechanism for doing this in both directions.

Last time we discussed this, I pointed you to the C++ FAQ that
explains this; it's already been cited in this thread. I even
demonstrated how to do it and posted the output. For some reason you
still didn't believe me, and now you're claiming yet again that it
can't be done.

Please consider the possibility that you might be wrong.

I did. That's why I used the "normally altered" phrase.
 
P

Pawel Dziepak

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
You are quoting from, I believe, the C++ standard. My point is
that C cannot call to C++ code, but C++ can call C code. The idea
is to prepare C object code and allow the C++ system to call it
correctly, by using the extern "C" identification _in the header
file for the C code_.

You don't have to use extern "C" in the header file for the C code. C
compilers assume that all functions symbols are in the C style.
extern "C" used in C++ code tell compiler that it has to create C style
symbol for that object (function/variable/whatever), so C code will be
able to call it.
The C++ standard is meaningless in c.l.c. Here, we use the C std.

This discussion is about C *and* C++.

Pawel Dziepak
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkkTbbEACgkQPFW+cUiIHNpeYQCfSnC6I6x/PhVfJ3rTN52Lhs++
R+MAn09HVzcm7O8bRrA39QIZwbWUsR5C
=+D/f
-----END PGP SIGNATURE-----
 
K

Keith Thompson

CBFalconer said:
I did. That's why I used the "normally altered" phrase.

Please consider the possibility that you might *still* be wrong.

One more time, it is possible to call C functions from C++ code, and
to call C++ functions from C code. The C++ standard defines the
mechanisms for doing this in both directions. Your statement above
that "In general, you just can't do that" is wrong.
 
B

Bill Reid

Keith Thompson said:
Chuck, we've had this discussion before. Yes, you can call C++
functions from C, and yes, you can call C functions from C++. C++
defines the mechanism for doing this in both directions.

Last time we discussed this, I pointed you to the C++ FAQ that
explains this; it's already been cited in this thread. I even
demonstrated how to do it and posted the output. For some reason you
still didn't believe me, and now you're claiming yet again that it
can't be done.

Please consider the possibility that you might be wrong.

Please consider the possibility that he might be
<sotto voce>insane</sotto voce>.

I mean, there is a total nadir of Usenet kookery, the
murky abyss where sense is nonsense and right is wrong
and reality can never escape the intense gravitational pull of
the completely collapsed nuerons of the infernally eternally
defiantly dense.

Also, please consider the possibility that YOU might
be insane if you ever try to correct him on this or the many
other topics he is wrong, according to this widely-accepted
measure:

"Insanity is doing the same thing over and over again and
expecting a different result."
 
J

James Kuyper

Flash said:
CBFalconer wrote, On 06/11/08 21:54:

If you're responding to what he wrote at that time, why don't you post
it as a response to the message in which he actually wrote it, on the
thread in which he wrote it? It's a little confusing to post it as a
response to a message I wrote, in a thread where he's said some
incorrect things about C/C++ linking, but he hasn't actually said these
particular incorrect things (at least, not yet):
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top