I know OpenCL has a C++ binder, but I use a third party library which is currently only working with CL.h. I want to write my program in C++. Is it safe to include cl.h in a C++ program and work with that in C style?
I saw some examples of including cl.h in C++ and they seem to be working. However, I don't know for sure. Is there any specific situation that may cause problems?
Yes. It is a C/C++ header with proper "extern "C" " guards.
http://www.khronos.org/registry/cl/api/1.0/cl.h
If it's a C header, you can wrap it in extern "C" directives:
extern "C"
{
#include "CL.h"
}
this tells the linker not to apply name mangling when looking for the functions declared in the header.
Related
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.
What I want to do:
I have autogenerated C Code generated with Matlab Simulink and want to enhance it with some more functionality written in C++. To be exact, the C code calls a C-style API that internally uses C++. The whole thing is in a VS 2008 C++ project.
The problem:
It compiles, as long as I tell VS to compile it as C and leave out my C++ code. As soon as I compile it as C++ problems arise.
First of all, I can't compile it as C++ because math.h produces an error C2668 due to an ambiguous call to an overloaded function (fabs()).
If I now additionally add some C++, e.g. include iostream, I get hundreds of compiler errors complaining about missing curly braces and misplaced colons somewhere in cstdlib.
My question:
How can I mix the two languages in a way that works? I read about preprocessor defines (http://www.parashift.com/c++-faq-lite/overview-mixing-langs.html) but I don't know how to apply them correctly to solve my problem.
Any help is greatly appreciated!
It seems you are including C++ headers in your C source code. Probably indirectly by including it in other header files (i.e. the C source include your C++ header, and the C++ header includes other C++ header files).
There are two ways of solving this:
Use the preprocessor to conditionally include the C++ headers only when compiled in C++. This can be done like
#ifdef __cplusplus
# include some_cpp_header
#endif
Don't include C++ headers (directly or indirectly) in your header files. Or better, make a separate header file whose only purpose is to be included in the C source, and which only contains the function prototypes (with extern "C" when compiled as C++) of the API. The body of the header file could look like this
#ifdef __cplusplus
extern "C" {
#endif
void function1(int);
int function2(const char*);
/* More function prototypes */
#ifdef __cplusplus
}
#endif
I recommend the second method.
Include the <iostream> library and then you'll have to compile your code with a c++-compiler.
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!
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.
I have a small program that I can compile with GCC and ICC without any difficulties, but I would also like the code to work with G++ and ICPC. I tried to add this:
#ifdef __cplusplus
extern "C" {
#endif
at the beginning and this:
#ifdef __cplusplus
}
#endif
at the end of all the header files, but I still get several `undefined reference to "..."' errors.
I think you're getting it wrong... The extern C is for disabling the function mangling; so if you do it just for the header files, when you try to link your mangled object code, the declared function names won't match with the function names in the object file.
Anyway, the extern C won't add any portability if the whole application is being compiled and linked with the same C++ compiler, it's intended for mixing C libraries with C++ code.
If your code is in the common subset of C and C++, you should be already able to compile it with either compiler, but I cannot see the reason to do that (besides working on the principle of least surprise, as C++ is more strict with some things).
You get undefined references because the declaration and the definition are not matching if you put extern "C", which prevents name mangling from happening: but in this case this is happening only in your header files.
If one of the undefined references is gxx_personality, then I'd say the post by "fortran" is correct.
See my response to this earlier question: When to use extern "C" in simple words?
It should hopefully make it clear how to mix C and C++ code.