How do you compile C++ source code that includes C source file? - c++

I'm attempting to use SQLite in a c++ program. My knowledge of C/C++ is limited as I've mostly used Java to this point. I had some classes in college but its been a while and we never covered anything like this. SQLite is written in C. When compiling the program how would you do this? (I have MinGW installed on my windows platform so gcc and g++ are what i use to compile.)

You protect the C headers in your C++ code by
extern "C" {
// your includes here
}
and that should be all---g++ should happily link code from both gcc and g++. The extern "C" ... trick is also used in C++ system headers and many libraries, just look at the headers that came with your g++ installation or some suitable Open Source projects. Here is a Boost example:
edd#max:~$ grep 'extern "C"' /usr/include/boost/date_time/*
/usr/include/boost/date_time/filetime_functions.hpp: extern "C" {
/usr/include/boost/date_time/filetime_functions.hpp: } // extern "C"
edd#max:~$
Edit: Thanks to delnan for an attentive comment---this is from the sqlite3.h header itself:
/*
** Make sure we can call this stuff from C++.
*/
#ifdef __cplusplus
extern "C" {
#endif
so this is of course already taken care of.

C++ achieves compatibility with C through the use of extern "C" declarations. There are some good explanations of what extern "C" means and why it is needed at this SO question: Why do we need extern “C”{ #include } in C++?. Virtually all C-based libraries, including sqlite, provide for automatic C++ compatibility by including extern "C" in their header files.
Therefore, SQLite will work without any special handling on your part (other than including the header and the library as you normally would for a C or a C++ library)...
/* my_sqlite_program.cpp */
#include <sqlite3.h>
int main()
{
...call sqlite functions...
}
compile with
g++ -Wall -Werror my_sqlite_program.cpp -lsqlite3 -o my_sqlite_program

For SQLite in specific, there's nothing really complicated about it.
If you're using a dynamic or static library, you just include their headers and link against the proper lib files.
If you're including SQLite fully inside your app, you'll need to include all the source files in your project and build them as well, and include the headers as needed (using it as a static/dynamic library might be nicer though).
If you need to use C code in files compiled as C++, Dirk's answer is correct, but that's not needed for SQLite.

How can you call C programs from C++ source code?
By using a facility called as linkage specification provided by the compilers. The specification tells the compiler how to link the source code.
Linkage specification is of the format
extern "Language_Type"
{
}
In your case you can wrap your SQLlite C functions like
extern "C"
{
//SQLite function declarations
}
This should enable you to get it working but Since you are trying to call SQlite c functions from C++, SQLite already provides some wrappers for achieving what you are trying to achieve. Check more details on SQLite website. Also, some open source projects also provide what you want. Check CppSQLite
Hope this helps!

Related

Linking to C libraries from C++: why isn't extern always needed?

Usually to get a C library working from C++ you have to include it with extern "C" { #include <clibrary.h> }. Many libraries will include in their header files code like #ifdef __cplusplus extern "C" { ... to make them more user friendly to C++ code (e.g. pthread.h). Sometimes this is not the case. For instance, stdio.h has no such #ifdef, yet I can still compile & link the usual #include <stdio.h> int main() {printf("Hello");} using a C++ compiler without wrapping it in an extern "C" statement. Why is this?
Usually to get a C library working from C++ you have to include it with extern "C" { #include <clibrary.h> }.
Only when the library was not designed with C++ compatibility in mind. But this is a hack.
Many libraries will include in their header files code like #ifdef __cplusplus extern "C" { ... to make them more user friendly to C++ code (e.g. pthread.h)
Yes, a good library will do this.
As a result, you do not need to and should not add another extern "C" around the #include.
stdio.h is an example of a header that will be doing this properly (see below).
For instance, stdio.h has no such #ifdef
Sure it does! Follow the money trail…
why isn't extern always needed?
So, in conclusion, you only need to do this yourself when the author of the header file didn't do it for you. When the author of the header file did it, you do not need to do it.
For instance, stdio.h has no such #ifdef
It probably does. Regardless, <stdio.h> is a header provided by the C++ standard library (inherited from the C standard library). It is guaranteed to work without extern "C" as are all standard headers.
Note that the usage of <name.h> name of the inherited standard headers in C++ instead of <cname> is deprecated in the current edition of the standard and has been identified as a candidate for removal in future revisions.
why isn't extern always needed?
Simply because some headers have been written to support C++ directly, and so do it by themselves.

Why could c++ include <stdio.h> and invoke printf method which is c(platform:ubuntu 14.04 compiler:gcc 4.8.4)

c++ compiler could compile code like this, and it executed correctly
#include <stdio.h>
int main() {
printf("test...\n");
return 0;
}
I think printf.c will be compiled to printf.o with c compiler, I just checked the stdio.h, there is no extern "C" keyword, then how could c++ linker link printf in printf.o which is compiled with c compiler?(By the way, my platform is ubuntu 14.04, compiler is gcc 4.8.4)
printf is part of the C++ standard library.
The <stdio.h> header that you include in the C++ source, belongs to the C++ standard library, and is not necessarily the same contents as a C compiler will include.
How the C++ implementation leverages the corresponding C implementation (if at all) is an implementation detail.
When C++ was originally made it was effectively a superset of C. That is to say, you can code perfectly good C in the C++ environment, just by ignoring all of the features that C++ adds. That, and because nowadays most C compilers are C++ compilers in which you can code C, is why you can use printf.
Secondly, no object code is generated for stdio because it is already a library, and so you are linking your own .o code against the already compiled stdio library code, which will be located somewhere in your compilers directory.
Nobody can give you a definitive answer without knowing what implementation you're using.
Cheers and hth. - Alf gave one possibility, which is that the stdio.h that is included by a C++ program may not be the same as the stdio.h that is included by a C program. Another possibility is that it is the same header, and there is an extern "C" block, and you just can't see it. For example, I use gcc, and my /usr/include/stdio.h contains a __BEGIN_DECLS macro, which expands to extern "C" { when compiled as C++. See Do I need an extern "C" block to include standard C headers?
You may not see an explicit extern "C" in stdio.h, but it is there. It's just hiding.
For example, on Linux, in stdio.h we see this:
#include <features.h>
__BEGIN_DECLS
In <features.h> you will find the following:
# ifndef _SYS_CDEFS_H
# include <sys/cdefs.h>
# endif
And in <sys/cdefs.h> you finally see:
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS
# define __END_DECLS
#endif
So, via a fairly roundabout path, Linux header files have a __BEGIN_DECLS/__END_DECLS wrapper which, when compiled by a C++ compiler, end up wrapping the whole thing inside extern "C".

Which would be the easiest way to turn folder with C headers into folder with C++ headers?

I am quite abeginner with all that C/C++ coding. Thay say that having C library with all headers turned into C++ in a fashon like:
#ifdef __cplusplus
extern "C" {
#endif
//.. header code
#ifdef __cplusplus
}
#endif
Will make it possibe to esely use practicly any C lib from sources (modified in such way). So I thought I shall give it at least a try. but I found I have like more than 300 headers... Ofcourse I will not use all of them but any way I'd prefere to make job once. So haw can I add such code to all headers? (I work with Windows, VisualStudio 2010 and 2008)
You only really need to do that if you have prebuilt C library code you are trying to interface your C++ code to.
If you still have the sources and are going to build all that C code yourself, you may find it easier to just submit them to the compiler as C++ code. With some compilers it is as simple as renaming the source files to *.cpp.
If that isn't workable, what I'd do is start with what you have, and only bother to put the extern "C" stuff around routines you need to use directly from your C++ code as you find them. That will surely be much less than the full 300 files, right?

How can we use any C library inside our C++ code?

How can we use any C library inside our C++ code? (Can we? Any tuts on that?) (I use VS10 and now talking about libs such as x264 and OpenCV)
Yes, the only thing you need to do is to wrap the #include statement with extern "C" to tell the C++ compiler to use the C-semantics for function names and such:
extern "C" {
#include <library.h>
}
During linking, just add the library like any normal C++ lib.
Well you can use any C library from your C++ code. That's one the cool thing with C++ :-)
You just have to include the libraries headers in your C++ code and link with the libraries you use.
Any good library handles its header inclusion from C++. If it is not the case you have to do it yourself with things like :
#ifdef __cplusplus
extern "C" {
#endif
#include "c_header.h"
#ifdef __cplusplus
}
#endif
Edit: As Mike said, the ifdef parts are only needed if you do not know if your file will be used with C or C++. You can keep them if the file is a header of an API header for example.
By the way, opencv handles the inclusion by C or C++ (thus you already have the #ifdef part in opencv headers). I do not know for x264 ...
my2cents
As far as I know, if you have the library you want to use, you just stick an include in your header file and you can use it.
from there on.

Using C/C++ static libraries from iPhone ObjectiveC Apps

Is it possible to have a C static library API, which uses C++ internally and hide this from users of the library?
I have writen a portable C++ library I wish to statically link to an iPhone application.
I have created an Xcode project using the Max OS X 'static library' template, and copied the source across, as well as writing a C wapper (to deal with exceptions) using (extern "C").
I am trying to use the generated library (.a file) in another Cocoa iPhone application.
Everything works well if the I use (.mm) extentions on the calling ObjectiveC file and (.cpp) on the implementation class in the library.
But I get unresolved symbols on linking when I try and change the wrapper file to a (.c) extention, even though all the wrapper function files are only C functions.
Just becuase C++ is used internally in a library, does it mean that externally it still must be treated as a C++ program. Is there not anyway to enforce this abstraction?
Edit: Thanks for the replies,
I had been using extern "C", I was just unsure about what configurations where needed in the calling project. ie. if the calling projected would require to know if it used C++ or could be ignorant and think its a purely C library.
It would seem I cannot, and I must use (.mm) files on my ObjectiveC classes.
It's too hard to do this in comments, so I'm just going to demonstrate for you quickly what the linking issues are that you're having. When Xcode encounters files, it uses build rules based on the suffix to decide which compiler to use. By default, gcc links the files to the standard C library, but does not link with the standard C++ library. Archive files (static libraries) have no linking resolution done at all. They are basically an archive of object files which need to be linked. Since you have no .mm or .cpp files in your project, g++ is never called and your files are never linked to the standard libraries. To correct this, just add the standard C++ libraries to your other linker flags in your Xcode project, or just simply add them to the pre-defined other flags option as -l (e.g., -lstdc++).
Here is a quick demonstration:
stw.h:
#ifdef __cplusplus
extern "C"
#endif
void show_the_world(void);
stw.cpp:
#include <iostream>
#include "stw.h"
using namespace std;
extern "C" void show_the_world() {
cout << "Hello, world!\n";
}
Build the library:
$ g++ -c stw.cpp -o stw.cpp -O0 -g
$ ar rcs stw.a stw.o
Using the library from a C application:
myapp.c:
#include "stw.h"
int main() {
show_the_world();
return 0;
}
Building the C application:
$ gcc -o myapp myapp.c stw.a -lstdc++ -g -O0
$ ./myapp
Hello, world!
$
If you try to compile without the -lstdc++ you will get all the unresolved issues because the C compiler has absolutely NO idea that it should link to the C++ runtime (and why would it, right!?!?) so you have to add this manually. The other option you have is to change the build rule for your project... instead of having Xcode use gcc to build .c and .m files, tell it to use g++ and your issues will be resolved.
You should declare the functions you want to be visible extern "C". Their signatures need to be C-compatible, but the contents do not (you may access C++ objects, for instance, but you cannot pass them directly; pointers are okay). The symbols will then be visible to any C-compatible environment.
EDIT: And compile it as a C++ source file, C doesn't have the notion of language linkage. There are a couple other gotchas with language linkage (like the fact that all extern "C" functions with the same name are the same function, regardless of namespace).
EDIT2: In the header, you can check for the macro __cplusplus, and use that to set for C++ and other languages, respectively (because C++ will require extern "C" declarations, and other languages will probably complain about them).
Basically when you compile the C functions with a C++ compiler it mangles the function names and uses the C++ ABI.
When you use the *.cpp or *.mm extension you are using the C++ compiler.
What you want to do is force the compiler to generate C functions with un-mangles names and using the C ABI.
You can do this by either:
Compile with the C compiler.
Compile with the C++ compiler but make sure that you prefix the function declarations with extern "C"
A favorite way to set up the header file, so that the same file can be included from both C and C++ source files is:
#ifndef HEADER_GUARD_1_H
#define HEADER_GUARD_1_H
#ifdef __cplusplus
extern "C" {
#endif
// Declare C function interface here.
int myFunc(int x,char*);
#ifdef __cplusplus
}
#endif
#endif
thanks, for such good discussion.
what I did is:
1) I created a static lib using cocaotouch static lib option. In that i have c/c++/obj-c all mix. however, my exports are only obj-c classes.
Infact i used objc- to c to C++.
2) then I creatd iphone app in X-code proj.
I added the otherlink flags my lib name ( -lxyz ) //my lib name is libxyz.a
I added lib search path, header search path
3) then I compiled. I got errors.
saying oeprator new, operator delete not found.
3) then apart my appdelegate, view controller, I added
dummy cpp(.h, .cpp)...
atestdummy.h atestdummy.cpp
4) then I build again...
thats it worked.
So - I whatever suggestions they gave earlier workedfor me.
basic reason, unless u r app sees a .cpp file .mm file with cpp code,
linked will not use g++.
Thanks all.
I have read the above and ssolved my problem.
u guys are good to share.