example c++ dll stl

example - vector double c++



Implicaciones del uso de std:: vector en una funciĆ³n exportada dll (2)

Desafortunadamente, su lista es muy acertada. La causa principal de esto es que DLL a DLL o DLL a EXE se define en el nivel del sistema operativo, mientras que la interfaz entre las funciones se define en el nivel de un compilador. En cierto modo, su tarea es similar (aunque algo más fácil) a la de la interacción cliente-servidor, cuando el cliente y el servidor carecen de compatibilidad binaria.

El compilador asigna lo que puede a la forma en que se realiza la importación y exportación de DLL en un sistema operativo en particular. Dado que las especificaciones de idioma dan a los compiladores mucha libertad cuando se trata del diseño binario de los tipos definidos por el usuario y, a veces, incluso de los tipos incorporados (recuerde que el tamaño exacto de int depende del compilador, siempre que se cumplan los requisitos mínimos de tamaño), la importación y exportación desde archivos DLL debe realizarse manualmente para lograr una compatibilidad de nivel binario.

Cuando usa la misma versión del mismo compilador, este último problema anterior no crea un problema. Sin embargo, tan pronto como un compilador diferente ingresa a la imagen, todas las apuestas están desactivadas: debe volver a las interfaces de tipo sencillo e introducir envoltorios para mantener interfaces de buen aspecto dentro de su código.

Tengo dos clases A y B exportadas por dll. La declaración de A contiene una función que utiliza un std :: vector en su firma como:

class EXPORT A{ // ... std::vector<B> myFunction(std::vector<B> const &input); };

(EXPORTAR es la macro habitual para colocar _ declspec (dllexport) / _declspec (dllimport) en consecuencia).

Al leer sobre los problemas relacionados con el uso de clases STL en una interfaz DLL, recojo en resumen:

  • El uso de std :: vector en una interfaz DLL requeriría que todos los clientes de esa DLL se compilen con la misma versión del mismo compilador porque los contenedores STL no son compatibles con los binarios. Lo que es peor, dependiendo del uso de esa DLL por parte de los clientes junto con otras DLL, la API DLL "inestable" puede interrumpir estas aplicaciones cliente cuando se instalan actualizaciones del sistema (por ejemplo, paquetes de Microsoft KB) (¿en serio?).

  • A pesar de lo anterior, si es necesario, std :: vector se puede usar en una API de DLL mediante la exportación de std::vector<B> como:

    template class EXPORT std::allocator<B>; template class EXPORT std::vector<B>;

    sin embargo, esto generalmente se menciona en el contexto cuando uno quiere usar std :: vector como miembro de A (http://support.microsoft.com/kb/168958).

  • El siguiente artículo de soporte de Microsoft explica cómo acceder a los objetos std :: vector creados en una DLL a través de un puntero o referencia desde el ejecutable (http://support.microsoft.com/default.aspx?scid=kb;EN-US; Q172396). La solución anterior para usar template class EXPORT ... parece ser aplicable también. Sin embargo, el inconveniente resumido en el primer punto parece permanecer.

  • Para deshacerse completamente del problema, uno tendría que ajustar std :: vector y cambiar la firma de myFunction , PIMPL, etc.

Mis preguntas son:

  • ¿Es correcto el resumen anterior, o echo de menos algo esencial?

  • ¿Por qué la compilación de mi clase ''A'' no genera la advertencia C4251 (la clase ''std :: vector <_Ty>'' necesita tener una interfaz dll para ser utilizada por los clientes de ...)? No tengo desactivadas las advertencias del compilador y no recibo ninguna advertencia sobre el uso de std :: vector en myFunction en la clase A exportada (con VS2005).

  • ¿Qué se necesita hacer para exportar correctamente myFunction en A? ¿Es viable simplemente exportar std::vector<B> y el asignador de B?

  • ¿Cuáles son las implicaciones de devolver std :: vector by-value? Suponiendo un ejecutable cliente que se ha compilado con un compilador diferente (-version). ¿Persiste el problema cuando se devuelve un valor por donde se copia el vector? Supongo que si. De manera similar, para pasar std :: vector como una referencia constante: ¿podría acceder a std::vector<B> (lo que podría haber sido construido por un ejecutable compilado con un compilador diferente (-versión)) myFunction causar problemas dentro de myFunction ? Supongo que sí otra vez ..

  • ¿Es el último punto de la lista anterior realmente la única solución limpia?

Muchas gracias de antemano por sus comentarios.


He estado teniendo el mismo problema y descubrí una solución limpia.
En lugar de pasar std:vector , puede pasar un QVector desde la biblioteca Qt .
Los problemas que usted cita se manejan dentro de la biblioteca Qt y no necesita lidiar con ellos en absoluto.
Por supuesto, el costo es tener que usar la biblioteca y aceptar su desempeño ligeramente peor.
En términos de la cantidad de tiempo de codificación y depuración que le ahorra, esta solución vale la pena.