i am running c code in vs2008. I was curious if i can mix this code with c++ code
The short answer is yes. However, there are some nuances.
C++ generally supports a large subset of C. It means that you can almost anything available in C (such as functions, libraries etc) from C++ code. From this point you have two options, an easy one and a bit harder.
Option #1 - Use C++ compiler.
Just have your code treated as C++. Simply put - use C++ compiler.
Option #2 - Mix C and C++.
You can write your C code and compile it with C++ compiler. Use C-like C++ where you need to use C++ components. For example, you may have a setup similar to the following:
head1.h - declarations of your C functions. For example:
void foo1();
header2.h - declarations of your C functions that intend to use C++ code.
#ifdef __cplusplus
extern "C" {
#endif
void foo2 ();
#ifdef __cplusplus
}
#endif
And two source files, one C and one C++:
source1.c
#include "header1.h"
#include "header2.h"
void foo1 ()
{
foo2 (); /* Call a C function that uses C++ stuff */
}
source2.cpp
#include <vector>
#include "header2.h"
#ifdef __cplusplus
extern "C" {
#endif
void foo2 ()
{
std::vector<int> data;
/// ... etc.
}
#ifdef __cplusplus
}
#endif
Of course, you will have to compile "cpp" files with C++ compiler (but you can still compile "c" files with C compiler) and link your program with standard C++ runtime.
The similar (but slightly more complicated) approach is used by Apple, for example. They mix C++ and Objective-C, calling the hybrid Objective-C++.
UPDATE:
If you opt for compiling C code as C++, I recommend you spend some time studying the differences between C and C++. There are cases when the code could be both legal C and C++, but produce different results. For example:
extern int T;
int main()
{
struct T { int a; int b; };
return sizeof(T) + sizeof('T');
}
If it is a C program then the correct answer is 8. In case of C++ the answer is 9. I have explained this in more details in my blog post here.
Hope it helps. Good Luck!
If you are compiling your code using C++ compiler as a C++ program then you can use std::vector.
If you are compiling your code using C compiler as a C program then you cannot.
This is because std::vector is a type defined by the C++ Standard, C Standard does not define any type as std::vector.
In simple words a C compiler does not understand what std::vector is.
There is a switch to compile .c files as C++ (/TP) . If you enable this, you can use the c as C++. Beware that some c code will not compile as C++ without modification (mainly to do with type casting; c++ has stricter rules for this).
If you are interfacing with some existing C library, then you of course can use C++. If you are compiling as C though, you won't be able to use any C++ features, such as std::vector.
Related
I'm writing a C program (myapp) which needs to use a particular api; the api is written in C++. I've worked with C and C++, but never both at once, and I'm getting confused.
So, the api provides the following directory, which I've placed in a folder called include, at the same level as my makefile:
libmyapi.a
api/api.h
My main source file is src/myapp.c, and it includes the api using #include "api/api.h".
My make command is (plus some flags, which I haven't listed because I don't think they're relevant here):
gcc -Linclude -lmyapi -Iinclude src/myapp.c -o lib/myapp.sp -lrt
The problem I'm having is that the api.h file contains references to namespaces etc. Eg at one point it has:
namespace MyAPI {
namespace API {
typedef SimpleProxyServer SimpleConnection;
}
}
and obviously the C compiler doesn't know what this means.
So, I assumed I'd need to compile using a C++ compiler, but then someone said I didn't, and I could just "wrap" the code in "extern 'C'", but I don't really understand. Having read around online, I'm not any further on.
Do I need to compile in C++ (ie using g++)?
Do I need to "wrap" the code, and what does that mean? Do I just do
#ifdef __cplusplus
extern "C" {
namespace MyAPI {
namespace API {
typedef SimpleProxyServer SimpleConnection;
}
}
}
#endif
or do I just wrap the lines
namespace MyAPI {
namespace API {
and then their corresponding }}?
The header file calls other header files, so potentially I'll need to do this in quite a lot of places.
So far I've got errors and warnings with all the variations I've tried, but I don't know whether I'm doing the wrapping wrong, setting g++ compiler flags wrong, using the wrong compiler, or what! If I know the method to use, I can at least start debugging. Thank you!
You can write a small C++ program that creates a C binding for the API.
Gvien this API:
namespace MyAPI {
namespace API {
typedef SimpleProxyServer SimpleConnection;
}
}
you can create c_api.h
#ifdef __cplusplus
extern "C" {
#endif
struct api_handle_t;
typedef struct api_handle_t* api_handle;
api_handle myapi_api_create();
void myapi_api_some_function_using_api(api_handle h);
void myapi_api_destroy(api_handle h);
#ifdef __cplusplus
}
#endif
and c_api.cpp
#include "c_api.h"
#include <myapi/api/stuff.hpp>
struct api_handle_t
{
MyAPI::API::SimpleConnection c;
};
api_handle myapi_api_create()
{
return new api_handle_t;
}
void myapi_api_some_function_using_api(api_handle h)
{
//implement using h
}
void myapi_api_destroy(api_handle h)
{
delete h;
}
compile that with a C++ compiler and include the c_api.h file in the C project and link to the library you created with the C++ compiler and the original library.
Basically, your C++ library needs to export a pure C API. That is, it must provide an interface that relies solely on typedef, struct, enum, preprocessor directives/macros (and maybe a few things I forgot to mention, it must all be valid C code, though). Without such an interface, you cannot link C code with a C++ library.
The header of this pure C API needs to be compilable both with a C and a C++ compiler, however, when you compile it as C++, you must tell the C++ compiler that it is a C interface. That is why you need to wrap the entire API within
extern "C" {
//C API
}
when compiling as C++. However, that is not C code at all, so you must hide the extern "C" from the C compiler. This is done by adding the preprocessor directives
#ifdef __cplusplus1
extern "C" {
#endif
//C API
#ifdef __cplusplus1
}
#endif
If you cannot change your libraries header, you need to create a wrapper API that offers this pure C API and calls through to the respective C++ code.
How do I call C++ functions from C?
By writing calling functions whose declarations are valid in the common subset of C and C++. And by declaring the functions with C language linkage in C++.
The problem I'm having is that the api.h file contains references to namespaces
Such header is not written in common subset of C and C++, and therefore it cannot be used from C. You need to write a header which is valid C in order to use it in C.
Do I need to compile in C++ (ie using g++)?
If you have function definitions written in C++, then you need to compile those C++ functions with a C++ compiler. If you have C functions calling those C++ functions, then you need to compile those C functions with C compiler.
A minimal example:
// C++
#include <iostream>
extern "C" void function_in_cpp() {
std::cout << "Greetings from C++\n";
}
// C
void function_in_cpp(void);
void function_in_c(void) {
function_in_cpp();
}
You cannot. You can use C functions in your C++ program. But you cannot use C++ stuff from C. When C++ was invented, it allowed for compatibility and reuse of C functions, so it was written as a superset of C, allowing C++ to call all the C library functions.
But the reverse is not true. When C was invented, there was no C++ language defined.
The only way you can call C++ functions is to convert your whole project into a C++ one... you need to compile your C functions with a C++ compiler (or a C compiler if they are plain C) but for a C function to call a C++ function it must be compiled as C++. You should declare it with:
extern "C" {
void my_glue_func(type1 param1, type2 param2, ...)
{
/* ... */
}
} /* extern "C" */
and link the whole thing as a C++ program (calling the c++ linker)
This is because C doesn't know anything about function overloading, class initializacion, instance constructor calls, etc. So if you even can demangle the names of the C++ functions to be able to call them from C (you had better not to try this), they will probably run uninitialized, so your program may (most) probably crash.
If your main() function happens to be a C function, then there's no problem. C++ was designed with this thing in mind, and so, main() is declared implicitly as extern "C". :)
I have a C++ library, with functions declared in a header file. My function declarations include default arguments.
I would like to use this library in Mathematica via the Wolfram Mathematica WSTP Template Compiler (wscc). This requires writing a C interface to my library. I have used this pattern
#ifdef __cplusplus
extern "C" {
#endif
double my_function(double x, double abs_error = 1E-3);
#ifdef __cplusplus
}
#endif
to prevent name-mangling in my library (compiled with C++). But what about the default arguments? I don't think they're standard C. From Wolfram Mathematica WSTP Template Compiler (wscc), I find
error: expected ‘;’, ‘,’ or ‘)’ before ‘=’ token
double abs_error = 1E-3,
Do I have to make separate C and C++ declarations (essentially two header files)? Is this a common problem or is it related to my use of wscc? Perhaps wscc doesn't support this syntax, although it is usually acceptable?
C does not support default arguments.
I'm therefore assuming you want to keep them for your C++ code, but you're okay with requiring C callers (in your case, Mathematica) to pass values for all arguments.
One possible approach is to define a macro which expands to the default value initializer in C++, but to nothing in C. It's not pretty, but it works:
#ifdef __cplusplus
#define DEFAULT_VALUE(x) = x
#else
#define DEFAULT_VALUE(x)
#endif
#ifdef __cplusplus
extern "C" {
#endif
void foo(int x DEFAULT_VALUE(42), void *y DEFAULT_VALUE(nullptr));
// In C, this becomes void foo(int x, void *y);
// In C++, this becomes void foo(int x = 42, void *y = nullptr);
#ifdef __cplusplus
}
#endif
Rather than macro hackery to work around the fact that C does not support default arguments, I'd introduce a layer of indirection.
First a C++ specific header that your C++ code uses (which I arbitrarily name interface.h.
double my_function_caller(double x, double abs_error = 1E-3);
and a C specific header (which I arbitrarily name the_c_header.h)
double my_function(double x, double abs_error);
/* all other functions that have a C interface here */
In practice, one would probably want include guards in both headers.
The next step is a C++ compilation unit (which I arbitrarily name interface.cpp) that actually interfaces to mathematica
#include "interface.h"
extern "C" // this is C++, so we don't need to test __cplusplus
{
#include "the_c_header.h"
}
double my_function_caller(double x, double error)
{
return my_function(x, error);
}
Then there is just the question of how to call the function. If the caller is C++, then all it needs to do is
#include "interface.h"
// and later in some code
double result = my_function_caller(x);
double another_result = my_function_caller(x, 1E-6);
If the caller is C (built with a C compiler) it simply does
#include "the_c_header.h"
/* and later */
result = my_function(x, 1E-3);
another result = my_function(x, 1E-6);
There are obviously advantages and disadvantages of this, compared with a macro-based solution, including;
None of the traditional disadvantages of macros (not respecting scope, no unintended interactions with other macros, running afoul of some C++ development guidelines that forbid usage of macros for anything except include guards).
Clear separation of which code is C and which is C++: Only interface.cpp needs to take care to have both #include "the_c_header.h" and #include "interface.h" and worry about the mechanics of interfacing of C++ to C. Otherwise, C compilation units (compiled with a C compiler) only need #include "the_c_header.h" and C++ compilation units only need to #include "interface.h".
interface.h can use any C++ language features (not just default arguments). For example, all the functions it declares may be placed in a namespace named mathematica if you wish. C++ developers using your functions need not care that there is actually an interface to C code buried away within that call.
If you decide in future to re-implement my_function() using something other than mathematica you can. Simply drop in the replacements of the_c_header.h and interface.cpp, and rebuild. The separation of concerns means that it is unnecessary to change interface.h, that all C++ callers will not even need to be recompiled in an incremental build (unless, of course, you change interface.h for some other reason).
Practically, the build process will detect mistaken usage of both header files. A C compiler will choke on interface.h because it uses C++-specific features. A C++ compiler will accept contents of the_c_header.h outside of an extern "C" context, but the result will be a linker error if any C++ code ever calls my_function() directly (linking will require a name-mangled definition).
In short, this takes a little more effort to set up than the macro approach, but is easier to maintain in the long run.
The extern C does more than stop name mangling. The function has C calling conventions. It's telling the CPP compiler "you should now speak C". That means exceptions won't propagate, etc. And AFAIK C doesn't have default values.
You can have a function with C calling conventions implemented inside a CPP file, which is very useful sometimes. You can have C calling bits of your CPU code, which is useful.
My suspicion is that how a compiler goes about dealing with default values is up to the compiler writer. If that's true, I can think of at least a couple of ways, one of them not involving putting a value for abs_error on the stack when my_function is called. For example the compiler might include a parameter count on the stack which the function itself uses to spot that abs_error has not been passed and to set a default value. However such a compiler would be very unfriendly indeed if it did that with a function that had C calling conventions without reporting errors. I think I'd test it, just to be sure.
guys.
I am writing an iOS app in swift, and I need to call some C++ lib. So I've build a simple example on how to bridge between C++ and Swift, and test on an iTouch. I wrapped the C++ interface with extern C. But I can't read the file when I call C++ function. Here is the code.
When I click the button on the iOS device, it needs to call the myFun():
main.swift
#IBAction func button(sender: AnyObject) {
myFun()
}
myFun() is my C++ function, which just reads a local file("hi.c").
DlibFun.cpp
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include "DlibFun.h"
#include <unistd.h>
void myFun(){
char* path = (char*)"/hi.c";
FILE* f = fopen(path, "r");
if(f != NULL){
printf("open it\n");
fclose (f);
}else{
printf("FAIL\n");
}
}
Wrapper the C++ code in C
DlibFun.h
#ifdef __cplusplus
extern "C" {
#endif
int myFun();
#ifdef __cplusplus
}
#endif
photo-Bridging-Header.h
#include "DlibFun.h"
The result is that every time it prints out "FAIL". And any one give me any hint? I have tried the different path, but none of them are correct. Is it possible that my path is wrong? or there is any thicky thing that I don't know?
File folder
As you said, the code in the question is a simple example. I don't think the problem you are asking about, namely the fact that "FAIL" is output, is related to the real difficulties of bridging between C++ and Swift. The C++ function is called correctly, but the file can't be opened, most likely because it isn't there or isn't readable. In fact, I reproduced your example in Xcode, and got the output "open it" as long as the file was available; otherwise it would be "FAIL," as in your case.
Because DlibFun.cpp includes DlibFun.h, where myFun() is declared extern "C", the C++ compiler will compile myFun() to have C linkage, meaning it can be called from C and Swift. When Swift sees myFun() through the bridging header, it just treats it as a C function and calls it as such.
In a real-world situation, myFun() would be implemented in some C++ library and compiled using a C++ compiler, giving it C++ linkage, so just creating a header in Xcode, declaring myFun() extern "C", and then including the header in the bridge won't help. The build will fail with a link error.
To call the C++ library function myFun() you can write a wrapper as follows:
///////////////////
// File DlibFunW.h:
#ifndef DlibFunW_h
#define DlibFunW_h
// Because this is a C file for use by Swift code, via
// the bridge header, we don't need #ifdef __cplusplus.
// And because myFunW() was marked extern "C" in our C++
// wrapper, it's just a C function callable from Swift.
void myFunW();
#endif /* DlibFunW_h */
////////////////////
// File DlibFun.cpp:
#include "DlibFun.h"
// This file is C++ because it calls myFun(), which is
// a function with C++ linkage.
// This code is visible only to the C++ compiler, so
// we don't need #ifdef __cplusplus
extern "C" void myFunW() { myFun(); }
Now we don't need extern "C" in DlibFun.h, since myFun() has C++ linkage, as a real-world C++ library function would. The bridging header is now just
#include "DlibFunW.h"
and Swift calls myFunW() instead of myFun().
Of course, this is a very simple example dealing only with the C vs. C++ linkage problem. A real-world C++ function would take parameters and return values, often of pointer, struct, and class types, and dealing with those is a completely different can of worms. Here on StackOverflow you'll find plenty of info on that. Some questions I'd recommend:
Swift converts C's uint64_t different than it uses its own UInt64 type
How do I get a specific bit from an Integer in Swift?
Converting inout values to UnsafeMutablePointer<Unmanaged<TYPE>?>
Is it possible to convert a Swift class into C void* pointer?
Can I mix Swift with C++? Like the Objective - C .mm files
Hope you find useful info there, all the best!
Suppose I have the following code, is something like that possible to do?
I mean passing a variable that is inside a c++ object to a function.
In foo.hpp
class foo
{
public :
int a;
}
in main.cpp
#include "cfile.h"
#include "foo.hpp"
void main()
{
foo * fooPtr = new foo();
int RetVal = MyCfunc(fooPtr->a);
}
In cfile.c
#include "cfile.h"
int MyCfunc(int var)
{
var + = 1;
return var;
}
Technically this compiles (well, after fixing various syntactic issues that have been pointed out already), but you have to be careful. You need to make sure everything can link (i.e. symbols are created correctly for both, C and C++ source code); I usually use g++ as a compiler which, for C files, works fine. Second, you have to make sure to tell your C++ code that you want to reference C code. Therefore, in your "cfile.h" you want to add
#ifdef __clpusplus
extern "C" {
#endif
// your C include file
#ifdef __cpluspus
}
#endif
That ensures that you can include your C include file into C++ sources, while telling the C++ compiler to use C style name mangling when compiling the code. Then go ahead and compile with C and C++ files, and link them into an executable:
g++ -g -O0 -o test main.cpp cfile.c
There is more about this here: Combining C++ and C - how does #ifdef __cplusplus work?
It would be better if you supplied an actual sample of what you're trying to do. As other have pointed out, the code you supplied has a number of syntax problems and passing basic types between C & C++ is mostly never a problem. An int is an int everywhere (as long as you aren't crossing 32/64 bit boundaries).
Where you can get into trouble is calling C/C++ functions/methods from the other side or passing classes around (use pointers and only pass them, usually, when in C code).
I have to import/translate the code from one C++ class so that I may use it in a C program.
The C program is large and has lots of dependencies on C libraries both open and closed.
The C++ Class .cpp file is 650 lines
I have no experience mixing C and C++ so even though I have looked at one guide on how to do it, I am not convinced which way to go.
I only have to use the C++ code in a few spots (fairly isolated useage
I am using gcc (gcc/g++)
It is a linux environment
So what do I have to do to import it? and will it be less time than translating?
Thanks,
Mike
Hmm, 650 lines is not too long - I'd re-write it. You will probably spend at least as much time trying to wrap it, and you may find maintaining the result difficult.
This might be useful: http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html
You need to create functions in C++ that are 'extern "C"', so they are callable from C.
You can get OO by making the this pointer explicit (and of type void *), with the implementation casting the pointer and forwarding to the real member function.
In your C++ code, you must use the extern "C" construct to instruct the compiler/linker to generate compatible linkage so that the C code can call your C++ code.
extern "C"
{
void my_function_that_can_be_called_from_c()
{
// ...
}
}
C code doesn't know anything about objects, so you can't easily use C++ objects from C. A common technique is to manipulate C++ objects inside the "externed" function.
Say you have the following C++ class:
#if __cplusplus // only C++ programs see this part of foo.h
class foo {
public:
// a couple constructors
foo();
foo( int);
// and a couple methods
bool dosomething();
bool doSomethingElse( std::string const&);
private:
// a bunch of private stuff which is immaterial to the C interface
}
#endif
What you can do is have a set of C-callable functions that wrap the C++ interface:
// both C and C++ programs can see this part of foo.h
#if __cplusplus // but C++ programs need to know that no name mangling should occur
extern "C" {
#endif
struct CFoo_struct;
typedef struct CFoo_struct foo_t; // used as a handle to a foo class pointer
// constructors
foo_t* CreateFoo( void);
foo_t* CreateFoo_int( int);
int CFooDoSomething( foo_t*);
int CFooDoSomethingElse( foo_t*, char const*);
#if __cplusplus
} // end the extern "C" block
#endif
Then the implementation in foo.cpp might look something like:
// in foo.cpp
extern "C" {
struct CFoo_struct {
};
// constructors
foo_t* CreateFoo( void)
{
foo* pFoo = new Foo;
// a bit of ugliness - the need for this cast could be
// avoided with some overhead by having the foo_t
// struct contain a foo* pointer, and putting a foo_t
// structure inside the foo class initialized with
// the this pointer.
return reinterpret_cast<foo_t*>( pFoo);
}
// something similar for CreateFoo_int()...
// method wrappers
int CFooDoSomethingElse( foo_t* pHandle, char const* s)
{
foo* pFoo = reinterpret_cast<foo*>( pHandle);
std::string str( s);
return pFoo->doSomethingElse( str);
}
// something similar for CFooDoSomething()
} // end extern "C" block
If you want to turn the C++ class into a Linux shared library accessible to your C programs, this answer to a previous question shows you how with a small example class.
There's various things you can do.
You can rewrite it in C. Without actually seeing the code, I don't know how much trouble that would be. Much C++ code is simply C with a few addons, and some makes heavy use of templates and overloaded functions and such.
If you're not doing this, you need to make it communicate well with C. This means providing an interface for C, and surrounding it with extern "C"{ ... } so the C++ compiler will know to make the interface C-compatible. Again, without knowing something of the C++ code, I can't tell how much work this would be. You'll need the wrapper for either of the following solutions.
You can make this a C++ project, surround every C file with extern"C" { ... }, and just link it in. If you have any C++ files, the whole compilation has to be C++.
You can make a separate library to be linked in.
What you can't do is compile C and C++ together with a C main() function, or with a C compiler. C++ is more demanding, and requires more from the main() function.
You could always try recompiling the C files you're using as C++, and wrapping the .h files for the libraries in extern "C" { ... }. Well-written C90 isn't that far from being legal C++ (although the C99 standard moved away from that some), and the compiler will flag any conversion problems you find.
Which of these is the best idea for you depends on questions like:
How easy is the C++ code to convert?
How easy is it to write a C wrapper for the C++ functionality you want?
How many changes are you willing to make to the C code?
How familiar are you with making a Linux library?