Pergunta

É válido desenvolver uma DLL em C ++ que retorna os ponteiros compartilhados do Boost e os usa como parâmetros?

Então, não há problema em exportar funções como essa?

1.) boost::shared_ptr<Connection> startConnection();
2.) void sendToConnection(boost::shared_ptr<Connection> conn, byte* data, int len);

Em especial: a contagem de referência funciona nos limites da DLL ou o requisito seria que o EXE e o DLL usariam o mesmo tempo de execução?

A intenção é superar os problemas com a propriedade dos objetos. Portanto, o objeto é excluído quando o DLL e o EXE não o referenciam mais.

Foi útil?

Solução

De acordo com Scott Meyers em C ++ eficaz (3ª edição), Shared_PTRS é seguro nos limites da DLL. O objeto Shared_Ptr mantém um ponteiro para o destruidor da DLL que o criou.

Em seu livro no item 18, ele afirma: "Uma característica especialmente agradável do TR1 :: shared_ptr é que ele utiliza automaticamente seu deleter por ponto para eliminar outro erro em potencial do cliente, o" problema cruzado ". Esse problema surge quando um um problema quando um um problema quando um um problema surge quando um um problema é O objeto é criado usando o novo em uma biblioteca dinamicamente vinculada (DLL), mas é excluída em uma DLL. Em muitas plataformas, esses pares de novos dll/excluir levam a erros de tempo de execução. Tr1 :: shared_ptr evite o problema, porque seu deleter padrão usa o exclusão da mesma DLL em que o TR1 :: shared_ptr é criado. "

Tim Lesher tem um Gotcha interessante para observar, porém, que ele menciona aqui. Você precisa garantir que a DLL que criou o Shared_PTR não seja descarregada antes que o Shared_PTR finalmente sai do escopo. Eu diria que, na maioria dos casos, isso não é algo que você precisa assistir, mas se você estiver criando DLLs que serão vagamente acoplados, eu recomendaria o uso de um shared_ptr.

Outra desvantagem potencial é garantir que ambos os lados sejam criados com versões compatíveis da biblioteca Boost. Shared_Ptr de Boost está estável há muito tempo. Pelo menos desde então 1.34 Tem sido compatível com TR1.

Outras dicas

Na minha opinião, se não estiver no padrão e não for um objeto/mecanismo fornecido pela sua biblioteca, não deve fazer parte da interface da biblioteca. Você pode criar seu próprio objeto para fazer a contagem de referência e talvez usar o Boost por baixo, mas ele não deve ser explicitamente exposto na interface.

As DLLs normalmente não possuem recursos - os recursos são de propriedade dos processos que usam a DLL. Provavelmente é melhor devolver um ponteiro simples, que você armazena em um ponteiro compartilhado no lado chamado. Mas sem mais informações, é difícil ter 100% de certeza sobre isso.

Algo para procurar se você expõe ponteiros crus de uma interface DLL. Ele obriga a usar a DLL compartilhada CRT, a memória alocada em um CRT não pode ser desalocada em um CRT diferente. Se você usar a DLL compartilhada CRT em todos os seus módulos (DLL's & EXE's), então você está bem, todos compartilham a mesma pilha, se não, você estará cruzando o CRT e o mundo se encaixará.

Além dessa questão, concordo com a resposta aceita. A fábrica de criação provavelmente não deve definir a propriedade e o gerenciamento do ciclo de vida para o código do cliente.

Não não é.

O layout de boost::shared_ptr<T> Pode não ser o mesmo nos dois lados do limite da DLL. (O layout é influenciado pela versão do compilador, Packing Pragmas e outras opções do compilador, bem como a versão real do código -fonte do Boost.)

Somente "Layout padrão" (um novo conceito em C ++ 11, relacionado ao antigo conceito "vod = antigo dados antigo") pode ser transmitido com segurança entre os módulos criados separadamente.

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