Pergunta

Eu tenho 2 estática objetos em 2 DLLs diferentes :

Um objeto Resources (que é um singleton), e um objeto Usuário . Objeto de usuário no seu destrutor tem de Recursos de acesso a objetos.

Como posso forçar Recursos objeto não deve ser destruído antes objeto de usuário?

Foi útil?

Solução

Objetos globais são destruídos quando sua DLL correspondente é descarregada. Assim como seu dll 'User' é provavelmente dependente de sua dll 'Recursos', você está em apuros:. 'Recurso' sempre será destruído antes 'usuário'

Eu também estou interessado por uma boa resposta a esta pergunta, se existir. Até agora, eu estou usando uma função de limpeza que deve ser chamado pelo aplicativo antes de ele sai, e eu só manter o código inofensivo em destruidores.

Outras dicas

Se você é capaz de colocar que 2 variáveis ??globais na mesma DLL não é a mesma história. Como dito por Jem em sua própria resposta, a fim Destacamento DLL não é garantida pelo sistema. Portanto, você pode ter um grande problema quando se tem 2 DLLs separadas. Eu não sou um guru do sistema Windows, mas ter um olhar com o Google, eu encontrei bloggers do MSDN que diz que eles tinham o mesmo problema com nenhuma boa solução para enfrentá-lo.

Eu você é capaz de colocá-los em uma mesma DLL, de acordo com mim a solução é mais fácil, nesse caso, você não precisa lidar com o "não GARANTIDO DLL Destacamento fim" questão (insolúvel, tanto quanto eu entendo) .
Mas, então, você ainda precisa enfrentar um novo problema: ordem global destruição variável não é garanteed pela linguagem C ++. Mas este pode ser abordada:

você precisa usar algum tipo de couting referência. um boost :: shared_ptr pode fazer o truque.

Declare-global e defini-lo dessa forma:

boost::shared_ptr my_resource_ptr ( new Resource() ); // new operator is important here!

Em seguida, você precisa modificar sua implementação de Usuário para Fechar o seu próprio shared_ptr:

class User
{
    ...
    boost::share_ptr a_resource_ptr;
    ...
};

Enquanto todos um da sua instância do usuário não é destruída, os vai 'reter' a instância de recurso, e assim impedir que ele seja prematuraly excluído, mesmo que o shared_ptr global poderia ter sido destruído.
A última instância do usuário sendo destruído vai (undirectly) excluir a instância de recurso.

Seja qual for a contagem de referência que você usa, ComPtr, seu próprio, ele deve fazer o truque.

Eu não acho que você pode alterar a ordem de destruição de globals que estão em módulos diferentes. Qualquer chance de adicionar algum contagem de referência?

No caso de você realmente deseja obter 2 separados PostRunOnce I pode ter algumas dicas para você: você pode considerar o uso de FreeLibrary() do Windows API. Tal como indicado por msdn FreeLibrary() decrementos um contador de referência para a DLL que é descarregado quando o contador chegar a 0.

Drawback: usando FreeLibrary() implica que você está carregando-lo com LoadLibrary() ( ligação MSDN) e chamando a função desta biblioteca implica que você está usando a função GetProcAddress(), o que pode levar a um código muito feio. E isso pode implicar alguma mudança no seu código também - como a obtenção de poiting variável global para as funções da DLL no fim de armazenar o endereço uns dos funções ...

Se você quiser implementá-lo:

  1. você deve carregar e libertar a biblioteca de sua função main() do seu processo,
  2. e também carregar e libertar a biblioteca da DLL implenting a classe de usuário. Implementá-lo na função DllMain() para este DLL, quando a razão é DLL_PROCESS_DETACH (veja o MDSN DllMain ligação .

Assim, ele irá descarregar a biblioteca "Resource" apenas uma vez a biblioteca "Usuário" tem acabamento com ele.

Tenha uma tentativa se você quiser e deixe-me dizer se ele funciona como eu nunca implementou ..

Ps: Eu tenho segunda resposta posta à sua pergunta para obter uma separação significativa entre as duas respostas como eu (tente) Detalhe ambos. Eu não quero que você misturá-las e ficar confuso ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top