Как разработать API C++ для двоичной совместимой расширяемости

Журнал Visual Studio имеет некоторые драгоценные камни каждый однажды в некоторое время

33
задан xpda 19 February 2013 в 05:24
поделиться

4 ответа

Several months ago I wrote an article called "Binary Compatibility of Shared Libraries Implemented in C++ on GNU/Linux Systems" [pdf]. While concepts are similar on Windows system, I'm sure they're not exactly the same. But having read the article you can get a notion on what's going on at C++ binary level that has anything to do with compatibility.

By the way, GCC application binary interface is summarized in a standard document draft "Itanium ABI", so you'll have a formal ground for a coding standard you choose.

Just for a quick example: in GCC you can extend a class with more virtual functions, if no other class inherits it. Read the article for better set of rules.

But anyway, rules are sometimes way too complex to understand. So you might be interested in a tool that verifies compatibility of two given versions: abi-compliance-checker for Linux.

32
ответ дан 27 November 2019 в 18:31
поделиться

В базе знаний KDE есть интересная статья, которая описывает, что можно и чего нельзя делать при написании библиотеки для обеспечения двоичной совместимости: Политики / Проблемы двоичной совместимости с C ++

11
ответ дан 27 November 2019 в 18:31
поделиться

Совместимость двоичных файлов C ++ обычно затруднена даже без наследования. Посмотрите, например, на GCC. Я не уверен, сколько критических изменений ABI произошло за последние 10 лет. Затем MSVC имеет другой набор соглашений, поэтому привязка к нему с GCC и наоборот невозможна ... Если вы сравните это с миром C, взаимодействие компилятора там будет немного лучше.

Если вы работаете в Windows, вам следует посмотреть COM. По мере введения новых функций вы можете добавлять интерфейсы. Затем вызывающие абоненты могут QueryInterface () для нового, чтобы раскрыть эту новую функциональность, и даже если вы в конечном итоге многое измените, вы можете либо оставить старую реализацию там, либо написать прокладки для старых интерфейсов .

1
ответ дан 27 November 2019 в 18:31
поделиться

Я думаю, вы неправильно понимаете проблему создания подклассов .

Вот ваш сутенер:

// .h
class Derived
{
public:
  virtual void test1();
  virtual void test2();
private;
  Impl* m_impl;
};

// .cpp
struct Impl: public Base
{
  virtual void test1(); // override Base::test1()
  virtual void test2(); // override Base::test2()

  // data members
};

void Derived::test1() { m_impl->test1(); }
void Derived::test2() { m_impl->test2(); }

Видите? Нет проблем с переопределением виртуальных методов Base , вам просто нужно заново объявить их virtual в Derived , чтобы те, которые были получены из Derived, знали, что они могут переписать их тоже (только если вы того пожелаете, что, кстати, является отличным способом предоставить финал для тех, кому его не хватает), и вы все еще можете переопределить его для себя в Impl , который может даже вызвать версию Base .

Там нет проблем с Pimpl .

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

1
ответ дан 27 November 2019 в 18:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: