Я хочу предоставить функцию сбора службы в моем приложении контейнера. Как часть этой функции, я хочу показать два интерфейса: «Сервис» и «Сервисная Реестр». Идея состоит в том, чтобы заставить различных поставщиков услуг добавлять свои реализации сервиса в коллекцию сервисов с помощью интерфейса реестра. Существует некоторое совпадение между пользователями приложений и сообществом поставщиков приложений.
Я думаю о следующих параметрах интерфейса службы:
/// Option 1
class Service
{
...
public:
virtual void doWork() = 0;
...
};
/// Option 2
using service_impl_type = std::function<void()>;
Я думаю о следующих параметрах интерфейса реестра:
/// Option A
class ServiceRegistry
{
...
public:
static void register( std::string const& name,
shared_ptr<Service> const& service );
...
};
/// Option B
namespace services
{
void register( std::string const& name,
service_impl_type const& service );
}
Приложение является частью общего объекта '' 'libContainer.so' '' и загружается исполняемым файлом '' 'контейнером' ''. Новые интерфейсы будут частью библиотеки libServices.so. '' 'LibContainer.so' '' будет зависеть от '' 'libServices.so' ''.
Поставщики услуг должны развернуть библиотеку '' 'libSvcProviderXYZ.so' '', содержащую их реализацию сервиса, в папке, известной приложению. Исполняемый файл «контейнера» динамически загружает общий объект (dlopen) и вызывает известную экспортированную функцию «registerYourself ()», которая будет присутствовать во всех библиотеках провайдера. Ожидается, что '' registerYourself () '' 'будет вызывать интерфейс реестра службы с реализацией службы синхронно.
У меня вопрос, может ли общий объект провайдера '' 'libSvcProviderXYZ.so' '' быть выгружен несколько раз после успешного завершения '' 'registerYourself ()' ''.
Если я перейду к варианту 1 и варианту A (для службы и реестра), поставщик xyz может предоставить следующее в '' 'libSvcProviderXYZ.so' '' ':
class ServiceImpl : public Service
{
public:
void doWork()
{
...
}
};
void registerYourself()
{
ServiceRegistry::register("xyz", std::make_shared<ServiceImpl>());
}
В этом случае я могу безопасно выгрузить общий объект поставщика '' 'libSvcProviderXYZ.so' '' после того, как '' registerYourself () '' 'завершится успешно? Если его можно выгрузить, что произойдет с информацией о типе '' 'ServiceImpl' '', представленной этой библиотекой провайдера?
Если я выберу вариант 2 и вариант B (для службы и реестра), провайдер xyz может предоставить следующее в '' 'libSvcProviderXYZ.so' '' ':
class ServiceImpl
{
public:
void operator()()
{
}
};
void registerYourself()
{
ServiceImpl impl;
services::register("xyz", impl);
}
В этом случае я могу безопасно выгрузить общий объект провайдера '' 'libSvcProviderXYZ.so' '' после того, как '' registerYourself () '' 'завершится успешно? Если он может быть выгружен, это из-за стирания типа ServiceImpl после копирования экземпляра в std :: function?
Большое спасибо заранее за любую помощь / совет в этом отношении!