Каковы возможные побочные эффекты ссылки на .lib, который является другой версией .dll? - PullRequest
3 голосов
/ 23 мая 2011

Я ссылаюсь на новый .lib, но использую более старый .dll в своем приложении.Каковы возможные побочные эффекты этого?Разве все не должно работать, если прототипы функций одинаковы между двумя версиями?Что если более новая версия изменит значение параметра по умолчанию?Будет ли это значение в .lib или .dll?

Ответы [ 4 ]

4 голосов
/ 23 мая 2011

В C ++ значения по умолчанию компилируются на сайте вызова - поэтому DLL или файл .lib не имеют к этому никакого отношения - изменение заголовка будет иметь эффект без изменений в ABI.

Если ABI в экспортируемых функциях не изменяется, вы сможете избежать использования старой библиотеки DLL с программой, связанной с более новым .lib, если программа не используетновый экспорт, который находится в новой .lib, но не в более старой DLL.

Вещи, которые влияют на ABI (я не утверждаю, что это полный список):

- calling convention
- export name
- parameter list (including types)

«Система управления версиями libtool» (http://www.gnu.org/s/libtool/manual/libtool.html#Versioning) - это метод определения совместимости совместно используемых библиотек.

Обратите внимание, что если вы не используете соглашение о вызовах C (т. е. имена экспорта будут "C ++ mangled")), то технически у вас мало контроля над экспортируемым именем.


Ниже приведено объяснение того, как некоторые библиотеки Windows (cygwin, pngdll) управляют обратной совместимостью с помощью именования.изобретение, которое следует методам управления версиями библиотеки libtool.Это из веб-архива http://home.att.net/~perlspinr/libversioning.html - я отражаю его здесь:

Пара определений:

точки входа доступны извне функции или переменные, экспортируемые DLL.Интерфейс - это набор всех этих экспортируемых функций и переменных в данной версии библиотеки.Относительно макросов версии libPNG в makefile.cygwin:

Вам ТОЛЬКО нужно поднять PNGDLL, если новая dll удаляет точку входа, предоставленную старой dll.Если вы добавляете новую точку входа, то новая DLL является заменой старой, поскольку новая предоставляет все, что делал старая.

Конечно, приложение скомпилировано с новой версией,который использует дополнительные точки входа, не будет работать со старой DLL - но никто никогда не обещал FORWARD-совместимость, только BACKWARD-совместимость.Вот как работает управление версиями библиотеки cygwin:

1) следуйте схеме управления версиями libtool. Из библиотек http://www.gnu.org/software/libtool/manual.html#Versioning:

So, libtool library versions are described by three integers:
current
    The most recent interface number that this library implements.
revision
    The implementation number of the current interface.
age
    The difference between the newest and oldest interfaces that this

реализуется библиотека.Другими словами, библиотека реализует все номера интерфейсов в диапазоне от номера текущий возраст до текущей.

Updating libtool versioning:

   1.     Start with version information of 0:0:0 for each libtool

библиотека.

   2. Update the version information only immediately before a

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

   3. If the library source code has changed at all since the last
      update, then increment revision (c:r:a becomes c:r+1:a).

   4. If any interfaces have been added, removed, or changed since the
      last update, increment current, and set revision to 0.

   5. If any interfaces have been added since the last public release,
      then increment age.

   6. If any interfaces have been removed since the last public
      release, then set age to 0. 


Never try to set the interface numbers so that they correspond to the
release number of your package. This is an abuse that only fosters
misunderstanding of the purpose of library versions. Instead, use the
-release flag (see Release numbers), but be warned that every

версия вашего пакета не будет двоично совместима с любым другим выпуском.

2) On windows/cygwin, the DLLVER is 'c - a' (trust me, this is correct,

но это легче объяснить на примере).

Итак, вот пример: версия libtool 5: 4: 3, что указывает на 4-ю версию реализации интерфейса 5, которая оказывается обратно совместимой стри предыдущих определения интерфейса.(т. е. для приложений, связанных с интерфейсами 5, 4, 3 и 2, безопасно загружать dll 5: 4: 3 во время выполнения).

Итак, давайте посмотрим на вероятную историю таинственной dll.Я следую описанным выше правилам обновления c: r:

oldest: interface definition 0, initial release:
0:0:0 (DLLVER = 0)    
removed an entry point:
1:0:0 (DLLVER = 1)    NOT backwards compatible!
but DLLVER does the right thing.
source code changed, but no added or removed entry points:
1:1:0 (DLLVER = 1)    
more source code changes:
1:2:0 (DLLVER = 1)    

In all of the previous three releases, 'c' - 'a' = DLLVER = 1.
removed an entry point (or renamed it):
2:0:0 (DLLVER = 2)    This is INCOMPATIBLE.
(But look: 'c' - 'a' = 2, so the DLLVER does the right thing)
added a new function:
3:0:1 (DLLVER = 2)    (this is BACKWARDS but not FORWARDS compatible.
However, the DLLVER 'c' - 'a' still is 2, so that is good.)
add eight more exported functions all at once
4:0:2 (DLLVER = 2)    
add another function:
5:0:3 (DLLVER = 2)
source code changes, but no new interfaces:
5:1:3 (DLLVER = 2)    
again:
5:2:3 (DLLVER = 2)    
again:
5:3:3 (DLLVER = 2)    
again:
5:4:3 (DLLVER = 2)    

Все эти библиотеки DLL с DLLVER = 2 (2: 0: 0, 3: 0: 1, 4: 0: 2,5: 0: 3, 5: 1: 3, 5: 2: 3, 5: 3: 3 и 5: 4: 3) строго обратно совместимы: гарантируется, что любая новая DLL в серии может быть загруженаexe, который был скомпилирован с более старой DLL в серии.

В 1.2.3 DLLVER был 12. Давайте представим, что это было «c» - «a» из 12, а это «c»= 12 и 'a' = 0.

В [libpng] 1.2.4 вы просто добавили несколько новых функций, но НЕ удалили их.Итак, новый номер libtool 13: 0: 1 - а DLLVER остается 12.

3 голосов
/ 23 мая 2011

НЕ ДЕЛАЙТЕ ЭТОГО.

Я уже имел дело с проблемами "новой LIB, старой DLL", и их действительно очень раздражает диагностировать. Это только «безопасно», если каждый публично видимый тип имеет точно такую ​​же сигнатуру, что в основном означает, что автор библиотеки должен сделать двоичную совместимость приоритетом. В противном случае вы получите причудливые ошибки повреждения кучи, которые часто не проявляются, пока программа не будет запущена некоторое время.

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

1 голос
/ 23 мая 2011

Это будет нормально, если и ТОЛЬКО если поддерживается двоичная совместимость между старой и новой версией dll.

В упрощенном виде.Если:

  • не было никаких изменений в файлах заголовков dll, используемых жгутом, и
  • никакие экспортированные символы не были добавлены или удалены, вы, вероятно, будете в порядке.

Если какое-либо из этих условий не будет выполнено, есть большая вероятность, что вы получите очень интересные ошибки / сбои / каракули памяти и т. Д.

1 голос
/ 23 мая 2011

Параметры по умолчанию должны быть в файле .h, так что эта часть, вероятно, в порядке.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...