I am trying to access a C++ class and call its method from a .c file.
I google this topic and find this http://developers.sun.com/solaris/articles/mixing.html
It says:
You can write
extern "C"functions in C++ that access classMobjects and call them from C code.
Here is a C++ function designed to call the member function foo:
extern "C" int call_M_foo(M* m, int i) { return m->foo(i); }
My question is where do I put the about line? In my C++ .h file? Or C .h file?
And it goes on and says:
Here is an example of C code that uses class M:
struct M; // you can supply only an incomplete declaration
int call_M_foo(struct M*, int); // declare the wrapper function
int f(struct M* p, int j) // now you can call M::foo
{
return call_M_foo(p, j);
}
But how/where do I create the class M in my C file?
And where do I put the above code? C .h file? C++ .h file? Or C .c file?
Thank you.
Thank you for GMan‘s detailed answer.
I did follow your suggestion. But I get compile error in my .c file.
main.c:33:
./some_class.h:24: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘attribute’ before ‘’ token
./some_class.h:25: error: expected ‘)’ before ‘’ token
./some_class.h:26: error: expected ‘)’ before ‘*’ token
And here are my some_class.h line 24-26:
#ifdef __cplusplus
class M {
public:
M();
virtual ~M();
void method1(char* name, char* msg);
};
extern "C" {
#else
struct M;
#endif
/* access functions line 24-26 are here*/
M* M_new(void);
void M_delete(M*);
void M_method1(M*, char*, char*);
#ifdef __cplusplus
}
#endif
For some reason, my C compiler does not like extern "C" in GMan‘s original some_test.h. So I have to modify to above. It seems like the C compiler does not like/understand the struct M; line.
Any idea will be much appreciated.
Your header file, which is shared between your C and C++ code:
Then your source file:
Now compile that source, and link to it. Your C source would be something like:
If you’re serious about mixing C and C++, you’ll want macro’s.
Here are some sample macro’s that would make this much easier:
And so on. Our header/source becomes:
And that’s much more concise. It could be made simpler (possibly) with variadic macro’s, but that’s non-standard and I leave that to you. :] Also, you can make macro’s for normal non-member functions.
Note that C does not know what references are. If you want to bind to a reference, your best bet is probably just to write the export definition manually. (But I’ll think about it, maybe we can get it automatically).
Imagine our
some_classtook thefloatby (non-const)reference (for whatever reason). We’d define the function like so:And there we go. C would interface with references with pointers instead:
And we pass
f“by reference”.