This question already has answers here:
How to call C++ function from C?
(7 answers)
Closed 5 years ago.
I have a header declaring functions that take pointers to C++ objects as parameters. The implementaton is in a seperate C++ file. How can I include this header in C and use the functions in C even though the arguments need to be C++ object pointers?
Unfortunately, my first attempt answered the wrong question....
For the question you did ask...
You can, as someone point out, pass around void *'s. And that's what I would also recommend. As far as C is concerned, pointers to C++ objects should be totally opaque.
C++ functions can be labeled extern "C" as well if they are in the global namespace. Here is an example:
myfunc.hpp:
#ifdef __cplusplus
extern "C" {
#endif
extern int myfunction(int, void *ob);
#ifdef __cplusplus
}
#endif
myfunc.cpp:
#include "myfunc.hpp"
void myfunction(int x, void *vobptr)
{
ClassType *ob = static_cast<ClassType *>(vobptr);
}
afoofile.c
#include "myfunc.hpp"
void frobble(int x, void *opaque_classtype_ptr) {
myfunction(x, opaque_classtype_ptr);
/* do stuff with buf */
}
The other option is to do basically the same thing with creative use of typedefs in C. This, IMHO, is quite ugly, but here is an example anyway:
myfunc.hpp:
#ifdef __cplusplus
extern "C" {
#else
typedef void ClassType; /* This is incredibly ugly. */
#endif
extern int myfunction(int, ClassType *ob);
#ifdef __cplusplus
}
#endif
myfunc.cpp:
#include "myfunc.hpp"
void myfunction(int x, ClassType *ob)
{
// Do stuff with ob
}
afoofile.c
#include "myfunc.hpp"
void frobble(int x, ClassType *opaque_classtype_ptr) {
myfunction(x, opaque_classtype_ptr);
/* do stuff with buf */
}
If your C code just needs to pass the pointers around, and eventually pass it back to some C++ that'll actually deal with the object it points to, you should be able to use a void * in the C code, and cast back to T * when it goes back into C++.
If you plan on the C code actually using the pointer, you're pretty much stuck with reverse engineering what your compiler happens to do, and trying to emulate it closely enough to make things work. Even at best, this is going to be ugly and fragile.
Make a wrapper module that's C++ but whose external functions are declared extern "C". This will allow you to access C++ code cleanly from C. Naturally the wrapper should replace any pointers to types not representable in C (i.e. classes) with either void pointers (the quick and dirty solution) or pointers to incomplete struct types (which would provide some level of type-safety as long as they're used consistently.
The secret is "extern C", whose primary purpose is the prevention of name decoration.
You can't. You'll have to create a C-compatible abstraction layer:
typedef struct foowrapper *foohandle;
foohandle foo_create();
void foo_delete(foohandle);
int foo_getvalue(foohandle);
void foo_dosomething(foohandle, const char* str);
Leaving this as after reading allsorts of posts on this topic, this was the easiest to follow.
http://research.engineering.wustl.edu/~beardj/Mixed_C_C++.html
Also, in netbeans the example ran out of the box without having to touch the makefile.
Check out this link:-
http://developers.sun.com/solaris/articles/mixing.html
The link contains the following topics:
Using Compatible Compilers
Accessing C Code From Within C++ Source
- Accessing C++ Code From Within C Source
Mixing IOstream and C Standard I/O
Working with Pointers to Functions
Working with C++ Exceptions
Linking the Program
Related
This question already has answers here:
Developing C wrapper API for Object-Oriented C++ code
(6 answers)
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
I have a nested class in C++ that I want C code to be able to use. Because it is nested I cannot forward declare it to C, so instead we have code like this in a shared header file:
#ifdef __cplusplus
class Mgr {
public:
class Obj {
public:
int x;
};
};
typedef Mgr::Obj * PObj;
#else
typedef void* PObj;
#endif
This results in C and C++ each seeing a different definitions of PObj which I fear violates the one definition rule. However it is "just" a pointer, so I'm not sure if this can go wrong or not.
C does nothing with the pointer besides pass it along to C++ functions which are wrappers for methods. For instance we'll have this in the combined header:
#ifdef __cplusplus
extern "C" {
#endif
int obj_GetX(PObj pObj);
#ifdef __cplusplus
}
#endif /* __cplusplus */
With this as the implementation in the C++ file:
int obj_GetX(PObj pObj) {
return pObj->x;
}
So:
Is this really a problem?
If so, what is the best way to share this pointer between C and C++
It's not a problem per-se, but you might violate the strict aliasing rule if and when you cast that void * back to Mgr::Obj * in your C++ code.
There's no good solution to this - it is (to me) a glaring omission in the standard. The best you can do is to compile any code which does such casts with the -fno-strict-aliasing flag. I do this extensively and have never had a problem performing casts in this manner.
My C++ program needs to use an external C library.
Therefore, I'm using the
extern "C"
{
#include <library_header.h>
}
syntax for every module I need to use.
It worked fine until now.
A module is using the this name for some variables in one of its header file.
The C library itself is compiling fine because, from what I know, this has never been a keyword in C.
But despite my usage of the extern "C" syntax,
I'm getting errors from my C++ program when I include that header file.
If I rename every this in that C library header file with something like _this,
everything seems to work fine.
The question is:
Shouldn't the extern "C" syntax be enough for backward compatibility,
at least at syntax level, for an header file?
Is this an issue with the compiler?
Shouldn't the extern "C" syntax be enough for backward compatibility, at least at syntax level, for an header file? Is this an issue with the compiler?
No. Extern "C" is for linking - specifically the policy used for generated symbol names ("name mangling") and the calling convention (what assembly will be generated to call an API and stack parameter values) - not compilation.
The problem you have is not limited to the this keyword. In our current code base, we are porting some code to C++ and we have constructs like these:
struct Something {
char *value;
char class[20]; // <-- bad bad code!
};
This works fine in C code, but (like you) we are forced to rename to be able to compile as C++.
Strangely enough, many compilers don't forcibly disallow keyword redefinition through the preprocessor:
#include <iostream>
// temporary redefinition to compile code abusing the "this" keyword
#define cppThis this
#define this thisFunction
int this() {
return 1020;
}
int that() {
return this();
}
// put the C++ definition back so you can use it
#undef this
#define this cppThis
struct DumpThat {
int dump() {
std::cout << that();
}
DumpThat() {
this->dump();
}
};
int main ()
{
DumpThat dt;
}
So if you're up against a wall, that could let you compile a file written to C assumptions that you cannot change.
It will not--however--allow you to get a linker name of "this". There might be linkers that let you do some kind of remapping of names to help avoid collisions. A side-effect of that might be they allow you to say thisFunction -> this, and not have a problem with the right hand side of the mapping being a keyword.
In any case...the better answer if you can change it is...change it!
If extern "C" allowed you to use C++ keywords as symbols, the compiler would have to resolve them somehow outside of the extern "C" sections. For example:
extern "C" {
int * this; //global variable
typedef int class;
}
int MyClass::MyFunction() { return *this; } //what does this mean?
//MyClass could have a cast operator
class MyOtherClass; //forward declaration or a typedef'ed int?
Could you be more explicit about "using the this name for some variables in one of its header files"?
Is it really a variable or is it a parameter in a function prototype?
If it is the latter, you don't have a real problem because C (and C++) prototypes identify parameters by position (and type) and the names are optional. You could have a different version of the prototype, eg:
#ifdef __cplusplus
extern "C" {
void aFunc(int);
}
#else
void aFunc(int this);
#endif
Remember there is nothing magic about header files - they just provide code which is lexically included in at the point of #include - as if you copied and pasted them in.
So you can have your own copy of a library header which does tricks like the above, just becoming a maintenance issue to ensure you track what happens in the original header. If this was likely to become an issue, add a script as a build step which runs a diff against the original and ensures the only point of difference is your workaround code.
I have a bunch of C code. I have no intention to convert them into C++ code.
Now, I would like to call some C++ code (I don't mind to modify the C++ code so that they are callable by C code).
class Utils {
public:
static void fun();
}
class Utils2 {
public:
static std::wstring fun();
}
If I tend to call them with the following syntax, they wont compiled (I am using VC++ 2008, with C code files with .c extension)
Utils::fun();
// Opps. How I can access std::wstring in C?
Utils2::fun();
Any suggestion?
// c_header.h
#if defined(__cplusplus)
extern "C" {
#endif
void Utils_func();
size_t Utils2_func(wchar_t* data, size_t size);
#if defined(__cplusplus)
}
#endif
//eof
// c_impl.cpp
// Beware, brain-compiled code ahead!
void Utils_func()
{
Utils::func();
}
size_t Utils2_func(wchar_t* data, size_t size)
{
std::wstring wstr = Utsls2::func();
if( wstr.size() >= size ) return wstr.size();
std::copy( wstr.begin(), wstr.end(), data );
data[wstr.size()] = 0;
return str.size();
}
//eof
What about a wrapper
extern "C" void Utilsfun(int i){Utils::fun(i);}
Update:
That is how you can call C++ functions from C, but accessing std::wstring from C is a different matter.
If you really wanted to manipulate C++ classes from C code then you could create an API where the classes are operated on with C++ functions, and passed back to C using void pointers. I've seen it done, but it's not ideal
extern "C"
{
void * ObjectCreate(){return (void *) new Object();}
void ObjectOperate(void *object, char *parameter){((Object*)object)->Operate(parameter);}
void ObjectDelete(void *object){delete ((Object*)object);}
}
You will have to be very careful about managing creating and deleting.
The most common solution is to write a C interface to your C++ functions. That is C++ code which are declared using extern "C" { ... }. These wrapper functions are free to call any C++ code they like, but since they're declared extern "C", they won't be subject to name mangling (you can't do namespaces or overloading here).
That ought to be linkable with your C file and you're good to go.
That is, the header file contains
#ifdef __cplusplus
extern "C" {
#endif
void wrapper1(void);
int wrapper2(int x);
char* wrapper3(int y);
#ifdef __cplusplus
}
#endif
The ifdefs are required to shield the C compiler from the extern "C".
And you implement those in your C++ source
void wrapper1(void) { Util::funcOne(); }
int wrapper2(int x) { return Util::funcTwo(x); }
char* wrapper3(int y) { return Util::funcThree(y); }
Create a wrapper function in your C++ code:
extern "C" void Wrapper() {
Utils2::fun();
}
and then in your C code:
extern void Wrapper();
int main() {
Wrapper();
return 0;
}
I think the only solution is to wrap them in C style global functions in the C++ code like:
extern "C" int Util2_Fun() { return Util2::Fun(); }
I suppose you could also declare global function pointers as externs using some nasty variation of:
extern int (*Utils2_Fun)()=(int *())(Util2::Fun);
And then call the function pointer directly from the C package using this pointer but there is little to recommend this approach.
You can make C++ callable from C by using the extern "C" construct.
If you do as ppl say here (using extern "C") beware that you only pass objects to the C function that would compile in C.
You won't have any practical use for c++ objects in your C code, so you'll probably want to create some sort of "C Binding" for your C++ code which consists of some number of ordinary functions that are callable from the C, and only return ordinary C data types. Your wrapper functions can then call all sorts of classes and objects, etc. But, they provide a simpler C-Style interface for the objects that you can use from C to bridge the gap. You can also use function pointers in some cases to give the C access to static methods, but it's usually easiest just to create the wrapper, IMHO.
You can either write global extern "C" wrapper functions or use function pointers to additionally make static class functions known to C. The C++ code can put these pointers in a global structure or pass them to C while calling a C function as a parameter. Also, you could establish a registry where the C code can request function pointers from C++ by supplying a string id. I've these all these varieties being used.
If you have control of all of the source, I wouldn't bother trying to keep part of it as C. It should be compilable as C++ (or easily changed to make it so). That doesn't mean you need to rewrite it as C++, just compile it as such. This way you can use whatever parts of C++ make sense. Over time, the C code make turn more C++ like, but this will happen slowly as the need arises.
Of course, if you need it to remain compilable in C for other reasons, this doesn't apply.
C is a subset of C++ ..
So u can not call c++ Class members and namespaces in C.
I've been reading questions on Stack Overflow for a few weeks now... this'll be my first question.
So recently I've looked into making C access/manipulate a C++ class. I understand that ideally one shouldn't compile components in C and C++ separately under normal circumstances, but this isn't an option at the moment.
I looked into 3 Tutorials regarding being able to port/use a C++ in C. They are:
"A Guide to C++ and C Interoperability" on DevX
"Mixing C and C++ Code in the Same Program" article on Sun's site.
"[32] How to mix C and C++" on Parashift
First, what I already know:
You must use extern "C" to avoid
C++ function name mangling.
You need callback prototypes that are C-compatible.
G++ must compile the C++ into .o files, GCC compiles the C-specific code into .o files, then link both after.
As a result, the project I have is made of 4 files:
foo.h, header that'll list all prototypes that C/C++ will see (classes invisible to C of course)
foo.cpp containing the Foo class, and a set of C-compatible callback functions to invoke the class and methods.
fooWrap.c a set of C-specific wrappers that reference the callback functions in foo.cpp.
main.c the test method.
Here's the code I typed up, then my questions:
FOO.H
// Header File foo.h
#ifndef FOO_H
#define FOO_H
//Content set inside this #ifdef will be unseen by C compilers
#ifdef __cplusplus
class Foo
{
public:
void setBar(int);
void printBar();
private:
int bar;
};
#endif
//end of C++-only visible components.
#ifdef __cplusplus
extern "C" {
#endif
//Stuff made to be seen by C compilers only. fooWrap.c has definitions.
#if defined(__STDC__) && !defined(__cplusplus)
typedef struct Foo Foo;
//C-wrappers for C++ callback functions.
Foo * c_NewFoo();
void c_SetFooBar( Foo *, int);
void c_PrintFooBar( Foo *);
#endif
//These are the functions C++ AND C can both use...
Foo * newFoo(); //allocates the memory for Foo class, pass address back.
void setFooBar( Foo * , int ); //set internal contents of Foo object.
void printFooBar ( Foo * ); //print internal contents of Foo object.
#ifdef __cplusplus
}
#endif
#endif /*FOO_H*/
TEST.C
#include "foo.h"
// test.c test file for wrappers that manipulate C++ objects.
main()
{
//looks very C++ like... this makes C-Programmers cringe doesn't it?
Foo * cfoo = c_NewFoo();
Foo * cppfoo = newFoo();
//using the C-specific wrappers.
c_SetFooBar(cfoo,31415);
c_PrintFooBar(cfoo);
//using the C/C++ callback functions to Foo objects.
setFooBar(cppfoo,9001);
printFooBar(cppfoo);
}
So I split the definitions up into the 4 files as I mentioned before... and it compiles fine. But here's what I don't quite get.
Why do the sun and parashift articles suggest to create C-Wrappers whose only code is to pass it's arguments onto C/C++ compatible functions who then call C++ specific code?
i.e.
//in Stuff.cpp
void CallCppStuff () { /* c++ stuff */ }
//in wrapStuff.c
wrapCppStuff() { CallCppStuff() }
As you can see from my test.c file... I'm able to call up either set of calls without a problem (as far as I can tell). Are the c_ wrappers needless overhead, or am I missing the whole point of them altogether? My only guess has something to do with pointer addressing schemes of C/C++... but I'm not sure.
Also, I imagine there are more issues beyond just this... but those 3 sites are all I could find specific to this problem. So if there are any other glaring oversights on my part, I'd appreciate their mentioning.
Thanks in advance for any help/advice,
CX
If you have a series of functions that are not object-orientated or in a namespace, there's no need to wrap them again. Your c_ series of functions are redundant.
Any C++ function that is extern C, has global (i.e., not namespace/static member) linkage, and only takes C-compat datatypes (normally we use opaque pointers like you have), then it doesn't need to be wrapped. That is the wrapping function. C++ uses member functions directly and doesn't need to use them, and they certainly don't need to be duped.
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?