c++ calling c functions

T

teju

hi,

i am trying 2 merge 2 projects into one project.One project is using c
language and the other one is using c++ code.

both are working very fine independently.But now i need to merge both
and my c++ code should call c code.but when i tried to call a function
in c code externing that function in my c++ code, i am getting
unresolved external symbol error. Whatever i try its giving more and
more errrors...so is it possible to merge 2 projects?

if so how can i do that?

please reply....

- Thejaswini
 
S

Sheth Raxit

hi,

i am trying 2 merge 2 projects into one project.One project is using c
language and the other one is using c++ code.

both are working very fine independently.But now i need to merge both
and my c++ code should call c code.but when i tried to call a function
in c code externing that function in my c++ code, i am getting
unresolved external symbol error. Whatever i try its giving more and
more errrors...so is it possible to merge 2 projects?

if so how can i do that?
this is nice article about what you want <mixing of c and c++ code>
http://developers.sun.com/solaris/articles/mixing.html
hope it will helpful.
please reply....

- Thejaswini

-Raxit Sheth
 
C

CBFalconer

teju said:
i am trying 2 merge 2 projects into one project.One project is
using c language and the other one is using c++ code.

both are working very fine independently.But now i need to merge
both and my c++ code should call c code.but when i tried to call
a function in c code externing that function in my c++ code, i am
getting unresolved external symbol error. Whatever i try its
giving more and more errrors...so is it possible to merge 2
projects?

if so how can i do that?

Follow the following organization. The result works for both C and
C++.

----------- note from here on --------------
/* a C header file for linking to C++ */

/* the normal provisions for skipping on a second request */

#ifdef __cplusplus
extern "C"
{
#endif

/* Here is the complete .h file, as used in C */
/* barring the above skip on second request */

#ifdef __cplusplus
}
#endif
--------- end of repaired c header -------

By the way, all this is perfectly standard ISO C.
 
B

Bill Reid

CBFalconer said:
Follow the following organization. The result works for both C and
C++.

We're getting closer here...
----------- note from here on --------------
/* a C header file for linking to C++ */

....or C++ header file for linking to C...
/* the normal provisions for skipping on a second request */
....and here are any normal external data declarations...then for
the external function declarations:
#ifdef __cplusplus
extern "C"
{
#endif

/* Here is the complete .h file, as used in C */

No, just the external function declarations, in the usual form:

extern void my_callable_function(void);
....

If you are calling a C function from C++, that is all you need to do.
However, check your external C++ function declarations carefully
for return values and arguments of types not derived from or of the
fundamental types allowed by the C programming language.

If so, you can't call that function from C. You'll have to write a
C++ "wrapper" function to translate the arguments and/or return
value into allowed C types, or in some other way modify your
include file typedefs or C++ source to account for this discrepancy.
/* barring the above skip on second request */
???

#ifdef __cplusplus
}
#endif
--------- end of repaired c header -------

By the way, all this is perfectly standard ISO C.

Well, yeah, in general...
 
D

Default User

teju said:
hi,

i am trying 2 merge 2 projects into one project.One project is using c
language and the other one is using c++ code.

You want the newsgroup comp.lang.c++. First, find their FAQ, which I
believe has a section on this topic.




Brian
 
J

jameskuyper

CBFalconer wrote:
....
No, you can't link C++ to C, in general.

I'm curious in what sense you mean that. C++ provides the concept of C
language linkage, and I believe that most C++ implementations support
that feature. Without getting into the details of how it works, it's
supposed to allow precisely what you've said can't be done. Are you
saying that most C++ implementations don't support this feature? Are
you saying that this feature doesn't work, or that it does work in
some special cases, but that in general it doesn't? Could you expand
upon that?
 
C

CBFalconer

Keith said:
I don't believe that's correct. Further information would be
topical in comp.lang.c++, not in comp.lang.c (since it's C++, not
C, that defines the mechanisms), but see questions 32.5 and 32.6
in the "C++ FAQ Lite" at <http://www.parashift.com/c++-faq-lite/>.

The point is that C++ function names are modified, to express the
parameter types, in the linkable object code sections. C does not
do this, since it doesn't have shared function names etc. Thus the
C++ code can be told (with the "extern C {...}") that selected C
functions are to be accessed (from C++) with unmodified names. The
reverse is not possible.

Thus I gave the general method for making C object code available
to aa C++ program.

Maybe we are confusing the direction of linking? You can call C
from C++, but not C++ from C (without impossible diddling).
 
C

CBFalconer

CBFalconer wrote:
...

I'm curious in what sense you mean that. C++ provides the concept of C
language linkage, and I believe that most C++ implementations support
that feature. Without getting into the details of how it works, it's
supposed to allow precisely what you've said can't be done. Are you
saying that most C++ implementations don't support this feature? Are
you saying that this feature doesn't work, or that it does work in
some special cases, but that in general it doesn't? Could you expand
upon that?

See my reply to Keith.
 
I

Ian Collins

CBFalconer said:
Maybe we are confusing the direction of linking? You can call C
from C++, but not C++ from C (without impossible diddling).
No, we have been here at least once before.

A C++ function declared as extern "C" may be called from C, that's one
of the reasons C++ has the linkage specifier. It is also used to
identify C function prototypes.

Otherwise C++ would not be able to call C library functions which have a
function pointer as a parameter.
 
K

Keith Thompson

CBFalconer said:
The point is that C++ function names are modified, to express the
parameter types, in the linkable object code sections. C does not
do this, since it doesn't have shared function names etc. Thus the
C++ code can be told (with the "extern C {...}") that selected C
functions are to be accessed (from C++) with unmodified names. The
reverse is not possible.

Thus I gave the general method for making C object code available
to aa C++ program.

Maybe we are confusing the direction of linking? You can call C
from C++, but not C++ from C (without impossible diddling).

No, I'm asserting that it's possible to call C from C++ *and* to call
C++ from C.

The C++ FAQ agrees, and directly contradicts your claim. Its authors
certainly know C++ better than I do.

Furthermore, I've just done it. Here are my source files:

==> func.h <==
#ifdef __cplusplus
extern "C" {
#endif
void func(int i, char c, float x);
#ifdef __cplusplus
}
#endif

==> func.C <==
#include "func.h"
#include <iostream>
void func(int i, char c, float x)
{
std::cout << "In func, sizeof 'a' = " << sizeof 'a' << "\n";
std::cout << "i = " << i << ", c = '" << c << "', x = " << x << "\n";
}

==> c_main.c <==
#include "func.h"
#include <stdio.h>
int main(void)
{
printf("In C main, sizeof 'a' = %d\n", (int)sizeof 'a');
func(42, '$', 123.456);
return 0;
}

==> cpp_main.C <==
#include "func.h"
#include <iostream>
int main()
{
std::cout << "In C++ main, sizeof 'a' = " << sizeof 'a' << "\n";
func(42, '$', 123.456);
return 0;
}

Here's the output of the C main program:

In C main, sizeof 'a' = 4
In func, sizeof 'a' = 1
i = 42, c = '$', x = 123.456

Here's the output of the C++ main program:

In C++ main, sizeof 'a' = 1
In func, sizeof 'a' = 1
i = 42, c = '$', x = 123.456

<OT>Both main programs had to be linked with "g++", because both need
the C++ standard library.</OT>

But as you can see the C program was compiled as C and successfully
called a C++ function.

Obviously this requires some compatibility between the C and C++
implementations.
 
M

Mark McIntyre

Keith said:
<OT>Both main programs had to be linked with "g++", because both need
the C++ standard library.</OT>

This is where this 'goes wrong' I think...
But as you can see the C program was compiled as C and successfully
called a C++ function.

I don't think so. The C++ compiler would have turned func into something
like func::func@as:33:22 or some such other decorated nonsense. The C
compiler would have generated a call to _func or whatever. The linker
can't resolve this.
The only way the modules will link is if main.lowercase-c was compiled
as C++ /OR/ if some implementation-specific magic went on to tell the
linker to look for multiple possible versions of the name.
Obviously this requires some compatibility between the C and C++
implementations.

Indeed - so _in general_ this isn't possible, as CBF said in the first
place?
 
R

Richard Heathfield

Mark McIntyre said:
This is where this 'goes wrong' I think...

No, not really. That was just a quick way to tell the linker how to do The
Right Thing.
I don't think so. The C++ compiler would have turned func into something
like func::func@as:33:22 or some such other decorated nonsense.

But wasn't it extern "C" qualified? The whole point of that - or at least
one of the points - is to switch off name-mangling.
The C
compiler would have generated a call to _func or whatever. The linker
can't resolve this.
The only way the modules will link is if main.lowercase-c was compiled
as C++ /OR/ if some implementation-specific magic went on to tell the
linker to look for multiple possible versions of the name.


Indeed - so _in general_ this isn't possible, as CBF said in the first
place?

To use a C library from a C program requires some compatibility between the
C implementation used for the library and the one used for the program. So
are you saying that, in general, it isn't possible to call C libraries
from C?
 
I

Ian Collins

Mark said:
This is where this 'goes wrong' I think...
Nope.


I don't think so. The C++ compiler would have turned func into something
like func::func@as:33:22 or some such other decorated nonsense. The C
compiler would have generated a call to _func or whatever. The linker
can't resolve this.

No it would not. The function was declared extern "C", so its name and
calling convections will be as they are in C.
The only way the modules will link is if main.lowercase-c was compiled
as C++ /OR/ if some implementation-specific magic went on to tell the
linker to look for multiple possible versions of the name.
Nonsense. If that were the case, no C++ application could call a C
library function.
Indeed - so _in general_ this isn't possible, as CBF said in the first
place?
Nonsense, the same applies to any two C compilers on the same platform.
 
J

James Kuyper

CBFalconer said:
The point is that C++ function names are modified, to express the
parameter types, in the linkable object code sections. C does not
do this, since it doesn't have shared function names etc. Thus the
C++ code can be told (with the "extern C {...}") that selected C
functions are to be accessed (from C++) with unmodified names. The
reverse is not possible.

Thus I gave the general method for making C object code available
to aa C++ program.

Maybe we are confusing the direction of linking? You can call C
from C++, but not C++ from C (without impossible diddling).

You can compile C++ routines after declaring that they have C linkage.
If you do so, they will be callable from C. In order for this to work,
the arguments and return type of the C++ function must use only features
in the common subset of C and C++. However, the body of the function can
use all features of C++ (though throwing an exception is problematic).

Therefore, you can't call all C++ functions this way, but you can call
any C++ functions that are designed to be called from C. And those
functions CAN call other C++ functions, without any of those restrictions.
 
J

James Fang

hi,

i am trying 2 merge 2 projects into one project.One project is using c
language and the other one is using c++ code.

both are working very fine independently.But now i need to merge both
and my c++ code should call c code.but when i tried to call a function
in c code externing that function in my c++ code, i am getting
unresolved external symbol error. Whatever i try its giving more and
more errrors...so is it possible to merge 2 projects?

if so how can i do that?

please reply....

- Thejaswini

Try
extern "C"
{
extern C_API();
}

in your cpp file , and then call the C_API().
 
M

Mark McIntyre

Richard said:
Mark McIntyre said:


No, not really. That was just a quick way to tell the linker how to do The
Right Thing.

Riight - implementation-specific magic, in other words!
But wasn't it extern "C" qualified?

I don't recall that, but ICBW. If so, the function in question wasn't
actually copmiled as C++ so I'm not sure it was a valid test...
To use a C library from a C program requires some compatibility between the
C implementation used for the library and the one used for the program. So
are you saying that, in general, it isn't possible to call C libraries
from C?


Correct. Try calliing a Turbo C 2 library from Watcom 32-bit C, or an
MSC 5 library from Vax C 5....
gd&r
 
M

Mark McIntyre

Ian said:
Nonsense. If that were the case, no C++ application could call a C
library function.

Firstly that's true, if the function isn't declared as extern "C".
Secondly we were dicsussing C calling C++, not the other way round.
Lastly compiling the C++ routine as C doesn't count.

Nonsense, the same applies to any two C compilers on the same platform.

Indeed, and more so between C and C++. So *in general* it isn't
possible, without invoking implementation-specific features.

You like the word nonsense, don't you? Myself I like the word
Balderdash, its much more evocative.
 
F

Flash Gordon

Mark McIntyre wrote, On 06/12/07 18:53:
Firstly that's true, if the function isn't declared as extern "C".
Secondly we were dicsussing C calling C++, not the other way round.
Lastly compiling the C++ routine as C doesn't count.

<snip>

Isn't it time for everyone to take this next door to comp.lang.c++ where
they know all about the compatibility between C and C++? Although they
will probably just point you at the FAQ and/or standard which tell you
how to make your C++ callable from C without compiling your C++ as C or
your C as C++.
 

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

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top