Regarding access / manipulation of a C ++ class in C

I've been reading stack overflow questions for several weeks ... this will be my first question.

Recently, I have studied the question of how to make C an accessible / governing C ++ class. I understand that, ideally, you cannot compile components in C and C ++ separately under normal circumstances, but at the moment this is not an option.

I reviewed 3 tutorials on the possibility of using / using C ++ in C. They are:

"C ++ and C Interoperability Guide " on DevX

"Mixing C and C ++ code in the same program" on Sun site.

"[32] How to mix C and C ++" on Parashift

First, what I already know:

  • You must use extern "C" to avoid the C ++ function name.

  • You need C callback prototypes compatible with C.

  • g ++ must compile C ++ to .o files, GCC compiles the C-specific code into .o files, and then links them after.

As a result, the project I created consists of 4 files:

  • foo.h, a heading that will list all the 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 for calling the class and methods.
  • fooWrap.c is a set of C-specific wrappers that reference callback functions in foo.cpp.
  • main.c testing method.

Here is the code I typed, 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 divided the definitions into 4 files, as I mentioned earlier ... and it compiles fine. But here I do not quite understand.

Why do articles with the sun and parachute offer suggest creating C-Wrappers, whose only code is to pass it arguments to C / C ++ compatible functions, which then call special C ++ 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 can call any set of calls without problems (as far as I can tell). Are c_ wrappers unnecessary overheads, or am I missing their purpose at all? My only suggestion has something to do with C / C ++ pointer addressing schemes ... but I'm not sure.

In addition, I believe that there are more problems besides this ... but these 3 sites are all that I could find, specific to this problem. Therefore, if on my part there are any other egregious glances, I will be grateful for their mention.

Thanks in advance for your help / advice, CX

+4
source share
1 answer

If you have a number of functions that are not object oriented or in the namespace, there is no need to wrap them again. Your number of c_ functions is redundant.

Any C ++ function that is extern C has a global one (i.e. not a namespace / static member), and accepts only C-compat data types (we usually use opaque pointers, just like you do), then this is not necessarily wrapped. This is a wrapping function. C ++ directly uses member functions and does not need to use them, and they, of course, need not be deceived.

+6
source

Source: https://habr.com/ru/post/1314822/


All Articles