Calling C++ static member functions from C 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:
st开发者_运维问答atic 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.
精彩评论