Онлайн-обновление приложения DLL

У меня есть подключаемое приложение, которое представляет собой библиотеку C++ DLL, работающую внутри (чужого) хоста C++. Я хочу разрешить онлайн-обновление подключаемого модуля. Как я могу это сделать?

Одним из возможных способов является разделение DLL на DLL-оболочку и DLL-библиотеку содержимого и переход на новую DLL-библиотеку содержимого при каждом обновлении.

Есть ли лучший способ добиться этого?

Спасибо


person kambi    schedule 05.07.2011    source источник
comment
переход на другую dll означает, что вам придется выгрузить ее, а затем снова загрузить. Следовательно, предлагаемое вами разделение на самом деле ничего не решит, так как вам все равно нужно выгрузить dll содержимого.   -  person stijn    schedule 05.07.2011


Ответы (3)


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

person Anteru    schedule 05.07.2011

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

В Windows (при условии, что Windows, поскольку вы сказали DLL), у вас есть проблема, поскольку вы не можете заменить исполняемый образ (включая библиотеки DLL) другим, пока он загружается в память. В POSIX это не проблема (и это даже надежно работает без каких-либо побочных эффектов!), но Windows заблокирует образ для монопольного доступа.

Поэтому у вас нет другого выбора, кроме как сначала выгрузить вашу DLL, затем заменить ее и снова загрузить. Это можно сделать так, как вы описали.

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

person Damon    schedule 05.07.2011

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

Кроме того, у вас может быть программа обновления в виде EXE (а не второй DLL), которая находится в папке автозапуска. Он загружает файл, если есть обновление, и копирует его в нужное место. Если это не удается из-за ERROR_ACCESS_DENIED, пользователь уже запустил приложение, и ваше обновление выполнит копирование при следующем входе пользователя в систему. Я думаю, что это проще, достаточно (это вам решать) и прозрачно для пользователя - он может удалить обновление из папки автозапуска или запустить его вручную.

person ur.    schedule 05.07.2011