Возможные проблемы совместимости, наследуемые от структуры C

Справочная информация: Мы реализуем динамическую библиотеку на C ++, которая расширяет функциональность программы на C. Для одной из основных структур, используемых в программе на Си, мы хотели бы добавить собственные поля, относящиеся к нашей библиотеке. В настоящее время, когда нам нужно новое поле, мы просим, ​​чтобы разработчики программы на C добавили нам поле, и в итоге у нас возникла большая проблема с кастингом. Мне было интересно, могли бы мы вместо этого сделать следующее:

Заголовочный файл основной программы:

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

Наш заголовочный файл:

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

Я думаю, у меня есть два вопроса:

1) Это даже законно?

2) Какие проблемы это создает, когда программа на Си пытается использовать часть структуры объекта?

0

Решение

Так как ImportantStruct является структурой POD (автоматически она имеет стандартную компоновку), и поскольку ObjectType не имеет других базовых типов и, если у нее нет виртуальных методов, она также имеет стандартную компоновку. Поэтому он может использоваться как структура в C.

1) Это даже законно?

Да, это.

2) Какие проблемы это создает, когда программа на Си пытается использовать часть структуры объекта?

Если ваша функция c не пытается перезаписать ее, вы в безопасности. Вы можете переписать это так:

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

Если это так, то это зависит от того, что находится в ImportantStruct, и есть ли заполненные байты.

Структура как это:

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

возможно, дополненные байты были удалены при создании базового класса.

В любом случае, я бы использовал композицию и избегал каких-либо проблем. Но вы должны убедиться, что это первый член, и что ObjectType имеет стандартную компоновку.

1

Другие решения

Производный подход должен работать, просто обратите внимание на итоговое выравнивание.
Я бы не делал предположений относительно результирующего размера / смещения в «расширенном» POD. Некоторые компиляторы могут удалять заполнение базового класса. Таким образом, производное P ++ C ++ может иметь размер, отличный от соотв. расширенная плоская структура С

Подробнее о макете производных объектов: с-данные выравнивание членов порядка наследование

Также для ваших целей расширения POD вы можете использовать struct ключевое слово над class, Не большая разница, просто члены структуры по умолчанию являются публичными.
Это также как бы выражает ваше POD-намерение (хотя и не применяется).

0

По вопросам рекламы [email protected]