I need to be able to mix C and C++.
The main program is written in C and needs to access C++ code.
To be more specific it's a user defined function in fluent, but this
should not be relevant.
I've allready read that i need to use the extern "C" construction but i
don't seem to be doing it right.
So far i've got this compiled:
<file: cpplib.cpp>
extern "C" int function(); //declaration
int function(){...} //definition
</file: cpplib.cpp>
<file: cpplib.h>
int function(){}
</file: cpplib.h>
<file: cprogram>
#include "cpplib.h"
...//call "function()" somewhere
</file: cprogram>
When i try to run it this generates the following error:
/opt/Fluent.Inc/fluent6.3.26/lnx86/2d/fluent.6.3.26: symbol lookup
error: libudf/lnx86/2d/libudf.so: undefined symbol: init
"init" is the function i'm trying to call here.
I'm hoping somebody here can give me an idea of what i'm doing wrong here.
Karel
#include "cpplib.h"
> int function(){...} //definition
> </file: cpplib.cpp>
>
> <file: cpplib.h>
> int function(){}
That's simply wrong. You shouldn't *define* functions in headers like
that. Think about it: the empty body? What you should have do is:
#ifdef __cplusplus
extern "C"
#endif
int function();
> </file: cpplib.h>
>
> <file: cprogram>
> #include "cpplib.h"
> ...//call "function()" somewhere
> </file: cprogram>
>
> When i try to run it this generates the following error:
> /opt/Fluent.Inc/fluent6.3.26/lnx86/2d/fluent.6.3.26: symbol lookup
> error: libudf/lnx86/2d/libudf.so: undefined symbol: init
> "init" is the function i'm trying to call here.
'init'? How does the 'init' play into all that? Isn't your function
called 'function'?
>
> I'm hoping somebody here can give me an idea of what i'm doing wrong here.
For one, you're not posting your real code.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
<file: cpplib.h>
#ifdef __cplusplus
extern "C" {
#endif
int init(); //declaration
#ifdef __cplusplus
}
#endif
</file: cpplib.h>
<file: cpplib.cpp>
#include "cpplib.h"
int init(){...} //definition
</file: cpplib.cpp>
<file: cprogram>
#include "cpplib.h"
...//call "init()" somewhere
</file: cprogram>
the result remains the same:
/opt/Fluent.Inc/fluent6.3.26/lnx86/2d/fluent.6.3.26: symbol lookup
error: libudf/lnx86/2d/libudf.so: undefined symbol: init
Karel
Which compilers do you use and how do you use them ?
If you use the gnu compiliers, you should use
g++ -c cpplib.cpp
and then
gcc cprogram.c cpplib.o
Greetings, Uwe
That's very unlikely to work. The main program must be compiled and
linked as C++.
--
Ian Collins.
So, more likely it should be
g++ -c cpplib.cpp
gcc -c cprogram.c
g++ cprogram.o cpplib.o -o cprogram
OK. Pardon a rank amature who only lurks here, BUT....
This looks like backwards logic to me. I thought that
'extern C' is a way for C++ code to call undecorated C code(?)
Not the otherway around!
Not that I have ever needed to face this, but I thought that C calling
C++ code needs some type of wrapper?
Confused?
Drew
These kinds of problems are really annoying sometimes however
unfortunately using both C and C++ are very common in real world (at
least my world =P). I'm certainly wondering what would be the "best"
practice for avoiding or even relaxing this kinds of issues.
cheers,
Alex Kim
Compile your C code with a c++ compiler :)
Most c++ compiler support C99 unless you disable it in the command line.
--
Michael
> >> If you use the gnu compiliers, you should use
> >> g++ -c cpplib.cpp
> >> and then
> >> gcc cprogram.c cpplib.o
> > That's very unlikely to work. The main program must be
> > compiled and linked as C++.
> So, more likely it should be
> g++ -c cpplib.cpp
> gcc -c cprogram.c
> g++ cprogram.o cpplib.o -o cprogram
If the main() is in cprogram.c, that still isn't guaranteed to
work. main() must be compiled as C++. (But since not doing so
is undefined behavior, it's possible that it works anyway, with
some implementations.)
--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
> > I've allready read that i need to use the extern "C"
> > construction but i don't seem to be doing it right.
> </snip>
> OK. Pardon a rank amature who only lurks here, BUT....
> This looks like backwards logic to me. I thought that
> 'extern C' is a way for C++ code to call undecorated C code(?)
No. 'extern "C"' tells the compiler to use C linkage, period.
A C++ function can be declared 'extern "C"', in which case, it
uses C linkage (but is C++ in every other way), and can be
called from a C program.
The classical example is the function passed to things like
pthread_create (Unix) or CreateThread (Windows); since this
function is called from C code, it must be 'extern "C"'.
> Not the otherway around!
> Not that I have ever needed to face this, but I thought that C
> calling C++ code needs some type of wrapper?
And how would you implement the wrapper? If you can't call C++
from C, you can't implement it in C, and if you implement it in
C++, you couldn't call it from C.
Typically, C++ code does require a wrapper, because it is using
argument types which C can't handle; the wrapper takes care of
any necessary type conversions. But thw wrapper itself is also
C++.
But all names cpplib.o are plain, because we used 'extern "C"' in
'function()'s declaration. So the linker will see no C++ mangled
symbolnames during linking.
Did I miss something ? Why should I use C++ compiler for compiling and
linking
a C program with some object file which looks like a C-object file ?
Greetings, Uwe
> On 4 Sep., 21:10, Ian Collins <ian-n...@hotmail.com> wrote:
>> Uwe Schmitt wrote:
>>
>> > Which compilers do you use and how do you use them ?
>>
>> > If you use the gnu compiliers, you should use
>>
>> > g++ -c cpplib.cpp
>>
>> > and then
>>
>> > gcc cprogram.c cpplib.o
>>
>> > Greetings, Uwe
>>
>> That's very unlikely to work. The main program must be compiled and
>> linked as C++.
>
> But all names cpplib.o are plain, because we used 'extern "C"' in
> 'function()'s declaration. So the linker will see no C++ mangled
> symbolnames during linking.
> Did I miss something ?
The public symbols exported by cpplib.o and used in cprogram aren't
the problem. The problem is that cpplib.o probably needs to link to
libstdc++. That happens by default when you use g++, but not with
gcc.
sherm--
--
My blog: http://shermspace.blogspot.com
Cocoa programming in Perl: http://camelbones.sourceforge.net
> > > Which compilers do you use and how do you use them ?
> > > If you use the gnu compiliers, you should use
> > > g++ -c cpplib.cpp
> > > and then
> > > gcc cprogram.c cpplib.o
> > That's very unlikely to work. The main program must be compiled and
> > linked as C++.
> But all names cpplib.o are plain, because we used 'extern "C"' in
> 'function()'s declaration. So the linker will see no C++ mangled
> symbolnames during linking.
So?
> Did I miss something ? Why should I use C++ compiler for
> compiling and linking a C program with some object file which
> looks like a C-object file ?
The C++ standard is quite clear: main() must be compiled as C++.
Depending on the compiler, it might work if this isn't the case,
or it might not, or somethings might work, and others not. In
particular, with some compilers, there's a very good chance that
static variables won't be initialized correctly if main isn't
compiled as C++.
And mangling really has not got much to do with the problem.
> >> > If you use the gnu compiliers, you should use
> >> > g++ -c cpplib.cpp
> >> > and then
> >> > gcc cprogram.c cpplib.o
> >> That's very unlikely to work. The main program must be
> >> compiled and linked as C++.
> > But all names cpplib.o are plain, because we used 'extern
> > "C"' in 'function()'s declaration. So the linker will see no
> > C++ mangled symbolnames during linking. Did I miss
> > something ?
> The public symbols exported by cpplib.o and used in cprogram
> aren't the problem. The problem is that cpplib.o probably
> needs to link to libstdc++. That happens by default when you
> use g++, but not with gcc.
The problem is also that static variables have to be
initialized; some compilers do this by generating special code
in main. Of course, if main wasn't compiled with a C++
compiler, it won't have that special code.
[ ... ]
> Most c++ compiler support C99 unless you disable it in the command line.
Really? All the C++ compilers I have handy seem to reject the following
perfectly legal bit of C99 code:
union {
char birthday[9];
int age;
float weight;
} people = { .age = 14 };
Even Comeau (which will accept it as C99 code) rejects it as C++ code
(quite rightly, I might add, since it's ill formed C++ code, and I don't
believe C++ 0x will allow it either).
Every other compiler I have handy (Microsoft, Digital Mars, gnu) rejects
it as either C or C++. gnu has a '-std=c99' flag, but appears to
implement little enough of C99 that it doesn't accept this even with
that flag.
--
Later,
Jerry.
The universe is a figment of its own imagination.
thanks, I learned something new :-)
Greetings, Uwe
--
Ian Collins.
I mean gcc accepts it when invoked with '-std=c99'. Jerry Coffin said
it did not. I am reporting that at least some recent versions do (as
they must if they want to compile C99).
For the record, the same gcc correctly rejects (or at least diagnoses)
VLAs when invoked as a conforming C++ compiler. The presence of a
default mixed mode where a compiler accept some odd half-language plus
extensions is unfortunate but common.
--
Ben.
>>>>> Most c++ compiler support C99 unless you disable it in the command line.
>>>> Really? All the C++ compilers I have handy seem to reject the following
>>>> perfectly legal bit of C99 code:
>>>>
>>>> union {
>>>> char birthday[9];
>>>> int age;
>>>> float weight;
>>>> } people = { .age = 14 };
>>>>
>>> Recent versions of gcc accept it.
>>>
>> gcc also accepts VLAs, but I doubt any other C++ compiler would.
>
> I mean gcc accepts it when invoked with '-std=c99'. Jerry Coffin said
> it did not. I am reporting that at least some recent versions do (as
> they must if they want to compile C99).
>
> For the record, the same gcc correctly rejects (or at least diagnoses)
> VLAs when invoked as a conforming C++ compiler. The presence of a
> default mixed mode where a compiler accept some odd half-language plus
> extensions is unfortunate but common.
>
That (gcc correctly rejects VLAs in C++ mode) is good. One of my worst
poring form gcc to standard C++ nightmares was scores of gcc VLAs.
--
Ian Collins.
[ ... ]
> Recent versions of gcc accept it.
I'm glad to hear that. What I was using isn't exactly current, but it's
not terribly old either -- it's good to hear that they're apparently
making a real attempt at C99 compliance (finally...)
True. I have overly generalized.
I was thinking of VLAs which tends to creep in so often. This code is
however accepted by my IAR c++ compiler.
More compliant c++ compiler will hopefully reject this code. But I guess
one could tweak them into accepting it.
--
Michael