Справочная информация: Мы реализуем динамическую библиотеку на 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) Какие проблемы это создает, когда программа на Си пытается использовать часть структуры объекта?
Так как 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 имеет стандартную компоновку.
Производный подход должен работать, просто обратите внимание на итоговое выравнивание.
Я бы не делал предположений относительно результирующего размера / смещения в «расширенном» POD. Некоторые компиляторы могут удалять заполнение базового класса. Таким образом, производное P ++ C ++ может иметь размер, отличный от соотв. расширенная плоская структура С
Подробнее о макете производных объектов: с-данные выравнивание членов порядка наследование
Также для ваших целей расширения POD вы можете использовать struct
ключевое слово над class
, Не большая разница, просто члены структуры по умолчанию являются публичными.
Это также как бы выражает ваше POD-намерение (хотя и не применяется).