devxlogo

Accessing a C++ Object in C Code: Support for Virtual Member Functions

Accessing a C++ Object in C Code: Support for Virtual Member Functions

In the case of virtual functions, an additional member is inserted into the class: a pointer to the virtual table, or _vptr. The _vptr holds the address of a static table of function pointers. The exact position of the _vptr among the class’ data members is implementation-dependent. Traditionally, it was placed after the user-declared data members. However, some compilers (Visual C++, for instance) have moved it to the beginning of the class for performance reasons. Theoretically, the _vptr can be located anywhere inside the class–even among user-declared members. Consider:

   class PolyDate  {  public:    int day;    int month;    int year;      Date();    virtual ~Date();  //polymorphic    bool isLeap() const;    bool operator == (const Date& other);  };

Defining a C struct that corresponds to the binary representation of a PolyDate object is more precarious in this case and requires intimate acquaintance with the compiler’s preferred position of the _vptr as well as with its size. Such a C struct might look like this code on some implementations:

   struct POD_Date  {    int day;    int month;    int year;    void * do_not_touch; /* the _vptr */  };

However, on other implementations (Visual C++, for instance) it might look like this:

   struct POD_Date  {    void * do_not_touch; /* the _vptr */    int day;    int month;    int year;    void * do_not_touch; //  };

Another hazard here is that the value of the _vptr is transient, which means that it might have a different value, according to the address space of the process that executes the program. Consequently, when an entire polymorphic object is stored in a file and retrieved later, the retrieved data cannot be used as a valid object. For all these reasons, accessing polymorphic objects from C code is dangerous and generally needs to be avoided.

devx-admin

Share the Post: