Я создаю C ++ API, который должен быть расширяемым без перекомпиляции программного обеспечения, которое его использует (по многим плохим причинам). Для этого требуются непрозрачные типы данных, чтобы поля можно было добавлять в классы. Что-то вроде
struct CheshireCat; // Not defined here
std::unique_ptr<CheshireCat> d_ptr;
Но этот API будет иметь множество простых методов получения / установки свойств, которые просто обращаются к полям в CheshireCat. (Я не хочу слышать о философии «инкапсуляции», это так, как это для этого приложения.)
Есть умные методы, которые создают классы, такие как MyInt, которые переопределяют операторы для эмуляции свойств, таких как
int & operator = (const int &i) { return value = i; }
operator int () const { return value; }
Но я не вижу какого-либо хорошего способа получения MyInt доступа к указателю CheshireCat в содержащем классе, не говоря уже о скрытых свойствах в структуре.
Кажется, что это должно быть очень распространенной проблемой, поэтому я ищу умные решения других людей. Возможно использование некоторой неясной макрологии.
(Альтернативы могут быть 1. Забудьте о бинарной совместимости или 2. Напишите много и много шаблонного кода вручную.)
Я понимаю, что для бинарной совместимости новые виртуальные методы должны быть добавлены до конца. Mangling зависит от компилятора, но должен быть стабильным для данного компилятора (мы отправим двоичные файлы, созданные для конкретного компилятора / версии).
Это похоже на C ++ 101, но я не смог найти ничего, что решило бы это элегантно. (Мой опыт работы с Java / .Net / Lisp, где JITing решает эту проблему. Система C ++, которая выполнила последние этапы компиляции в компоновщике (DLL), была бы превосходной, но, к сожалению, это не так.)
Я не думаю, что вы можете получить бинарную совместимость, выставив C ++.
Что вы можете сделать, это выставить интерфейс C (который является двоично-совместимым). Это означает, что, как вы уже намекали, раскрытие функций, которые работают с непрозрачными дескрипторами (то есть указателями).
Конечно, внутренности могут быть написаны на C ++.
Других решений пока нет …