Работа с файлами манифеста C++ Visual Studio

Массивы в основном такие же, как указатели на C / C ++, но не совсем. После преобразования массива:

const int a[] = { 2, 3, 5, 7, 11 };

в указатель (который работает без кастинга и, следовательно, может случиться неожиданно в некоторых случаях):

const int* p = a;

вы теряете способность sizeof для подсчета элементов в массиве:

assert( sizeof(p) != sizeof(a) );  // sizes are not equal

Эта потерянная способность называется «распад».

Для получения дополнительной информации ознакомьтесь с этим статья о распаде массива .

31
задан Voltaire 27 February 2009 в 19:08
поделиться

4 ответа

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

Это - то же на всех платформах. Это не что-то изобретенная Microsoft.

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

a.dll
    dllexport void* createBla() { return malloc( 100 ); }

b.dll
    void consumeBla() { void* p = createBla(); free( p ); }

, Когда a.dll и b.dll связаны с различным временем выполнения, это отказывает, потому что функции времени выполнения реализуют свою собственную "кучу".

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

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

Для ссылки:

  • не выделяют/освобождают память/объекты через границы модуля
  • , не используют сложные объекты в Вашем интерфейсе dll. (например, станд.:: строка...)
  • не используют тщательно продуманные механизмы C++ через dll границы. (typeinfo, исключения C++...)
  • ...

, Но это не проблема с декларациями.

декларация А содержит информацию о версии времени выполнения, используемого модулем, и встраивается в двоичный файл (exe/dll) компоновщиком. Когда приложение загружается, и его зависимости должны быть разрешены, загрузчик смотрит на явную информацию, встроенную в EXE-файл, и использует согласно версии времени выполнения dlls от папки WinSxS. Вы не можете только скопировать время выполнения или другие модули к папке WinSxS. Необходимо установить время выполнения, предлагаемое Microsoft. Существуют пакеты MSI, предоставленные Microsoft, которая может быть выполнена, когда Вы устанавливаете свое программное обеспечение на машине теста/конечного пользователя.

Так устанавливают Ваше время выполнения перед использованием Вашего приложения, и Вы не получите 'недостающую зависимость' ошибка.

<час>

(Обновленный к, "Как Linux избегает использования Файлов манифеста" вопрос)

, Что такое файл манифеста?

Файлы манифеста были представлены для размещения информации о разрешении неоднозначности рядом с существующим исполняемым файлом/динамически подключаемой библиотекой или непосредственно встроены в этот файл.

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

(Существует несколько других вещей, которые можно сделать с файлами манифеста, например, некоторые метаданные могут быть помещены здесь)

, Почему это сделано?

версия не является частью имени dll из-за исторических причин. Таким образом, "comctl32.dll" называют этим путем во всех версиях его. (Таким образом, comctl32 под Win2k отличается от того в XP или Vista). Для определения, которые присваивают версию Вам действительно, хотят (и протестировали против), Вы помещаете информацию о версии в "appname.exe.manifest" файл (или встраиваете этот файл/информацию).

, Почему это было сделано этот путь?

Много программ установили свой dlls в system32 каталог на systemrootdir. Это было сделано, чтобы позволить bugfixes общим библиотекам быть развернутым легко для всех зависимых приложений. И в эпоху ограниченной памяти, совместно использованные библиотеки уменьшили объем потребляемой памяти, когда несколько приложений пользовались теми же библиотеками.

Этим понятием злоупотребили многие программисты, когда они установили весь свой dlls в этот каталог; иногда перезаписывая более новые версии общих библиотек с более старыми. Иногда библиотеки, измененные тихо в их поведении, так, чтобы зависимые разрушенные приложения.

Этот вывод к подходу "Распределяют весь dlls в каталоге приложения".

, Почему это было плохо?

, Когда ошибки появились, весь dlls, рассеянный в нескольких каталогах, должен был быть обновлен. (gdiplus.dll) В других случаях, это даже не было возможно (компоненты окон)

явный подход

Этот подход, решает все проблемы выше. Можно установить dlls в центральном месте, где программист не может вмешаться. Здесь dlls может быть обновлен (путем обновления dll в папке WinSxS), и загрузчик загружает 'право' dll. (версия, соответствующая, сделана dll-загрузчиком).

, Почему Linux не имеет этого механика?

у меня есть несколько предположений. (Это действительно просто предполагает...)

  • , Большинством вещей является открытый исходный код, таким образом перекомпилировать для bugfix является надуманным вопросом для целевой аудитории
  • , поскольку существует только одно 'время выполнения' (gcc время выполнения), проблема с границами совместного использования/библиотеки во время выполнения не происходит так часто
  • , Много компонентов используют C на интерфейсном уровне, где эти проблемы просто не происходят при правильной организации
  • , версия библиотек в большинстве случаев встраивается от имени ее файла.
  • Большинство приложений статически связывается со своими библиотеками, таким образом, никакой dll-ад не может произойти.
  • время выполнения GCC было сохранено очень ABI, стабильным так, чтобы эти проблемы не могли произойти.
27
ответ дан 27 November 2019 в 22:41
поделиться

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

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

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

3
ответ дан 27 November 2019 в 22:41
поделиться

я наконец пришел к выводу, что единственный способ заставить это работать (помимо статичного соединения всего) состоит в том, что все сторонние библиотеки должны быть скомпилированы с помощью той же версии Visual Studio - т.е. не используют предварительно скомпилированный dlls - загружают источник, создают новый dll и использование это вместо этого.

, Кроме того (и решение мы должны использовать, где я работаю) то, что, если сторонние библиотеки, что необходимо использовать всех, создаются (или доступные, как создано) с той же версией компилятора, можно "просто" использовать ту версию. Это может быть перетаскивание для "" использования VC6, например, но если существует библиотека, которой необходимо пользоваться, и ее источник не доступен, и это - то, как это прибывает, опции печально ограничены иначе.

... насколько я понимаю.:)

(Моя строка работы не находится в Windows, хотя мы боремся с DLLs в Windows с пользовательской точки зрения время от времени, однако мы действительно должны использовать определенные версии компиляторов и получить версии стороннего программного обеспечения, которые все создаются с тем же компилятором. К счастью все поставщики склонны оставаться довольно актуальными, так как они делали этот вид поддержки много лет.)

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

Если сторонний DLL выделяет память, которую необходимо освободить, то DLL повредился, одно из главных правил поставки предварительно скомпилировало DLL. Точно поэтому.

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

3
ответ дан 27 November 2019 в 22:41
поделиться
Другие вопросы по тегам:

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