[C++] ¿Cómo paso con seguridad objetos, especialmente objetos STL, hacia y desde una DLL?


Answers

@computerfreaker ha escrito una gran explicación de por qué la falta de ABI evita pasar objetos de C ++ a través de límites de DLL en el caso general, incluso cuando las definiciones de tipo están bajo el control del usuario y la misma secuencia de token se usa en ambos programas. (Hay dos casos que funcionan: clases de diseño estándar e interfaces puras)

Para los tipos de objetos definidos en el Estándar C ++ (incluidos los adaptados de la Biblioteca estándar de plantillas), la situación es mucho, mucho peor. Los tokens que definen estos tipos NO son los mismos en múltiples compiladores, ya que el estándar de C ++ no proporciona una definición de tipo completa, solo requisitos mínimos. Además, la búsqueda de nombre de los identificadores que aparecen en estas definiciones de tipo no resuelve el mismo. Incluso en sistemas donde hay un ABI de C ++, intentar compartir dichos tipos a través de los límites del módulo da como resultado un comportamiento indefinido masivo debido a las infracciones de la regla de una sola definición.

Esto es algo a lo que los programadores de Linux no estaban acostumbrados, porque la libstdc ++ de g ++ era un estándar de facto y virtualmente todos los programas lo usaban, satisfaciendo así la ODR. la librería libc ++ de clang rompió esa suposición, y luego apareció C ++ 11 con cambios obligatorios para casi todos los tipos de bibliotecas estándar.

Simplemente no comparta tipos de biblioteca estándar entre módulos. Es un comportamiento indefinido.

Question

¿Cómo paso objetos de clase, especialmente objetos STL, hacia y desde una DLL de C ++?

Mi aplicación tiene que interactuar con complementos de terceros en forma de archivos DLL y no puedo controlar con qué compilador se crean estos complementos. Soy consciente de que no hay un ABI garantizado para objetos STL, y me preocupa causar inestabilidad en mi aplicación.




No puede pasar objetos STL de forma segura a través de los límites DLL, a menos que todos los módulos (.EXE y .DLL) estén compilados con la misma versión del compilador C ++ y las mismas configuraciones y sabores del CRT, lo cual es muy limitado y claramente no es su caso.

Si desea exponer una interfaz orientada a objetos desde su DLL, debe exponer las interfaces puras de C ++ (que es similar a lo que hace COM). Considere leer este interesante artículo sobre CodeProject:

HowTo: Exportar clases de C ++ desde una DLL

También puede considerar exponer una interfaz pura de C en el límite de la DLL y luego crear un contenedor de C ++ en el sitio de la persona que llama.
Esto es similar a lo que sucede en Win32: el código de implementación Win32 es casi C ++, pero muchas API Win32 exponen una interfaz C pura (también hay API que exponen las interfaces COM). Luego, ATL / WTL y MFC envuelven estas interfaces C puras con clases y objetos C ++.




Links