Question

Background: We're implementing a dynamic library in C++ that extends the functionality of a C program. For one of the main structs used in the C program, we would like to add our own library specific fields. Currently when we need a new field, we ask nicely that the developers of the C program add a field for us and we end up having a massive casting mess. I was wondering if we could instead do the following:

Header file of main program:

#ifdef __cplusplus
extern "C" {
#endif
/* ... */
typedef struct ImportantStruct {
/* Definitions */
} ImportantStruct
/* ... */
#ifdef __cplusplus
}
#endif

Our Header File:

//...
class ObjectType : public ImportantStruct {
// Our extra fields
}
//...

I guess I have two questions:

1) Is this even legal?

2) What problems does this create when the C program tries to use the struct part of the object?

Was it helpful?

Solution

Since the ImportantStruct is a POD structure (automatically it has standard layout), and since ObjectType doesn't have other base types and if it doesn't have virtual methods, it also has a standard layout. Therefore it can be used as a struct in C.

1) Is this even legal?

Yes, it is.

2) What problems does this create when the C program tries to use the struct part of the object?

If your c function doesn't try to over-write it, you are safe. You can overwrite it like this :

void foo( struct ImportantStruct *s )
{
 memset( s,0, sizeof(*s) );
}

If it does, then it depends on what is in ImportantStruct, and whether there are padded bytes.

Structure like this :

typedef struct {
  int a;
  char b;
} ImportantStruct;

might have padded bytes removed when made base class.

Anyway, I would use composition, and avoid any kind of problems. But you have to make sure it is the first member, and that the ObjectType has standard layout.

OTHER TIPS

The derived approach should work, just mind the resulting alignment. I would not make assumptions on the resulting size/offsets in the "extended" POD. Some compilers may remove padding of the base class. So the derived C++ POD may be of different size from resp. extended flat C struct.

More details on the layout of derived objects: c-data-alignment-member-order-inheritance

Also for your purposes of extending POD you may use struct keyword over class. Not a big difference, just the struct members are public by default. It also kind of expresses your POD-intent (though it's not enforced).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top