Accessing C++ objects from C
Related Blog Items
- How Bus Error occurs
- Stdarg: Variable Arguments
- Constant and Volatile
- Size of an empty class
- Differences between new, malloc; delete, free
Passing C++ objects to/from C function
Here’s an example
Fred.h:
#ifndef FRED_H
#define FRED_H
#ifdef __cplusplus
class Fred {
public:
Fred();
void wilma(int);
private:
int a_;
};
#else
typedef
struct Fred
Fred;
#endif
#ifdef __cplusplus
extern ”C” {
#endif
#if defined(__STDC__) || defined(__cplusplus)
extern void c_function(Fred*); /* ANSI C prototypes */
extern Fred* cplusplus_callback_function(Fred*);
#else
extern void c_function(); /* K&R style */
extern Fred* cplusplus_callback_function();
#endif
#ifdef __cplusplus
}
#endif
#endif /*FRED_H*/
Fred.cpp:
#include ”Fred.h”
Fred::Fred() : a_(0) { }
void Fred::wilma(int a) { }
Fred* cplusplus_callback_function(Fred* fred)
{
fred->wilma(123);
return fred;
}
main.cpp:
#include ”Fred.h”
int main()
{
Fred fred;
c_function(&fred);
…
}
c-function.c:
#include ”Fred.h”
void c_function(Fred* fred)
{
cplusplus_callback_function(fred);
}
Unlike your C++ code, your C code will not be able to tell that two pointers point at the same object unless the pointers are exactly the same type. For example, in C++ it is easy to check if a Derived* called dp points to the same object as is pointed to by a Base* called bp: just say if (dp == bp) …. The C++ compiler automatically converts both pointers to the same type, in this case to Base*, then compares them. Depending on the C++ compiler’s implementation details, this conversion sometimes changes the bits of a pointer’s value. However your C compiler will not know how to do that pointer conversion, so the conversion from Derived* to Base*, for example, must take place in code compiled with a C++ compiler, not in code compiled with a C compiler.
NOTE: you must be especially careful when converting both to void* since that conversion will not allow either the C or C++ compiler to do the proper pointer adjustments! For example (continuing from the previous paragraph), if you assigned dp and bp into two void* pointers, say dpv and bpv, it might be the case that dpv != bpv even if dp == bp. You have been warned.
directly accessing data in a c++ object from C function
Sometimes can be accessed.
You can safely access a C++ object’s data from a C function if the C++ class:
- Has no virtual functions (including inherited virtual functions)
- Has all its data in the same access-level section (private/protected/public)
- Has no fully-contained subobjects with virtual functions
If the C++ class has any base classes at all (or if any fully contained subobjects have base classes), accessing the data will technically be non-portable, since class layout under inheritance isn’t imposed by the language. However in practice, all C++ compilers do it the same way: the base class object appears first (in left-to-right order in the event of multiple inheritance), and member objects follow.
Furthermore, if the class (or any base class) contains any virtual functions, almost all C++ compliers put a void* into the object either at the location of the first virtual function or at the very beginning of the object. Again, this is not required by the language, but it is the way “everyone” does it.
If the class has any virtual base classes, it is even more complicated and less portable. One common implementation technique is for objects to contain an object of the virtual base class (V) last (regardless of where V shows up as a virtual base class in the inheritance hierarchy). The rest of the object’s parts appear in the normal order. Every derived class that has V as a virtual base class actually has a pointer to the V part of the final object.
source:USENET
[tags]accessing c++ objects from c[/tags]
Popularity: 5%
You need to log on to convert this article into PDF
Related Blog Items - How Bus Error occurs
- Stdarg: Variable Arguments
- Constant and Volatile
- Size of an empty class
- Differences between new, malloc; delete, free
Related Blog Items
- How Bus Error occurs
- Stdarg: Variable Arguments
- Constant and Volatile
- Size of an empty class
- Differences between new, malloc; delete, free
No Comments
No comments yet.