2009-12-24 10 views
10

¿Es válido desarrollar una DLL en C++ que devuelva impulsores compartidos y los use como parámetros?¿Está bien utilizar boost :: shared ptr en la interfaz DLL?

Entonces, ¿está bien exportar funciones como esta?

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

En especial: ¿El trabajo de referencia recuento a través de fronteras o DLL sería el requisito de que sea EXE y DLL utilizar el mismo tiempo de ejecución?

La intención es superar los problemas con la propiedad del objeto. Entonces el objeto se elimina cuando tanto dll como exe ya no hacen referencia a él.

Respuesta

10

De acuerdo con Scott Meyers en Effective C++ (3rd Edition), shared_ptrs es seguro a través de los límites de dll. El objeto shared_ptr mantiene un puntero al destructor desde el dll que lo creó.

En su libro en la casilla 18, afirma: "Una característica especialmente agradable de TR1 :: shared_ptr es que utiliza automáticamente su Deleter por triple eliminar a otro error del cliente potencial, el" problema cruzada DLL . " Este problema aparece cuando se crea un objeto utilizando una biblioteca enlazada dinámicamente (DLL) pero se elimina en una DLL diferente. En muchas plataformas, tales pares DLL-nuevos/eliminar llevan a errores de tiempo de ejecución. tr1 :: shared_ptr evita el problema, porque su eliminador predeterminado usa delete desde la misma DLL donde se crea tr1 :: shared_ptr. "

Tim Lesher tiene un interesante tema que observar, sin embargo, que menciona here. Debe asegurarse de que la DLL que creó shared_ptr no se descargue antes de que shared_ptr finalmente salga del alcance. Diría que en la mayoría de los casos esto no es algo que tengas que estar atento, pero si estás creando dlls que se acoplarán débilmente, recomendaría no usar un shared_ptr.

Otro posible inconveniente es asegurarse de que ambos lados se creen con versiones compatibles de la biblioteca de impulso. El shared_ptr de Boost se ha mantenido estable durante mucho tiempo. Al menos desde 1.34 ha sido compatible con tr1.

+2

CUIDADO: si enlaza la CRT estática, tendrá problemas. Cada módulo que está vinculado estáticamente al CRT obtiene su propio montón. Si todos los módulos se vinculan al DLL CRT, todos compartirán un montón. – Zac

2

Las DLL generalmente no poseen recursos propios: los recursos son propiedad de los procesos que usan la DLL. Probablemente sea mejor que devuelva un puntero simple, que luego almacena en un puntero compartido en el lado de la llamada. Pero sin más información, es difícil estar 100% seguro de esto.

4

En mi opinión, si no está en el estándar y no es un objeto/mecanismo provisto por su biblioteca, entonces no debería ser parte de la interfaz de la biblioteca. Puede crear su propio objeto para hacer el recuento de referencias y, tal vez, utilizar el refuerzo debajo, pero no debe exponerse explícitamente en la interfaz.

2

Algo a tener en cuenta si expone los punteros sin formato desde una interfaz dll. Te obliga a usar el dll CRT compartido, la memoria asignada en un CRT no se puede desasignar en un CRT diferente. Si utiliza el dll CRT compartido en todos sus módulos (dll's & exe), entonces está bien, todos comparten el mismo montón, si no cruza CRT y el mundo se derrumbará.

Aparte de ese problema, estoy de acuerdo con la respuesta aceptada. La fábrica de creación probablemente no debería definir la propiedad & gestión del ciclo de vida para el código del cliente.

+0

¿Cómo se puede asegurar de que exe y dll están utilizando dll CRT compartido? ¿Cuáles son las banderas del compilador para esto? –

0

No, no lo es.

El diseño de boost::shared_ptr<T> puede no ser el mismo en ambos lados del límite de la DLL. (El diseño está influenciado por la versión del compilador, los pragmas de empaquetado y otras opciones del compilador, así como la versión real del código fuente de Boost.)

Solo "diseño estándar" (un nuevo concepto en C++ 11 relacionado con el viejo tipo "POD = plain old data" concept) se puede pasar con seguridad entre módulos construidos por separado.

Cuestiones relacionadas