Pregunta

Tengo un DLL que necesita acceder a los datos almacenados en contenedores STL en la aplicación host. Debido a que C ++ no tiene ABI estándar, y quiero apoyar diferentes compiladores, la interfaz entre la aplicación y DLL, básicamente, tiene que seguir siendo llanura de edad-datos.

Para los vectores esto es relativamente sencillo. Puede devuelva el bloque de memoria del vector, ya que se garantiza que sea contigious:

// To return vector<int> data
virtual void GetVectorData(const int*& ptr, size_t& count) const
{
    if (!vec.empty())
        ptr = &(vec.front());

    count = vec.size();
}

Ahora el DLL puede tener acceso de lectura seguro a los datos del vector a través de esa interfaz. El DLL también puede envolver este para copiar el contenido en un vector por sí mismo también.

¿Qué hay de las listas (STL) y deques sin embargo? ¿Hay alguna otra forma sencilla de permitir el acceso a través de una frontera DLL? O voy a tener que recurrir a algún tipo de) / interfaz GetFirst (GetNext ()? Puede ser que necesite hacer esto por una gran cantidad de listas, por lo que sería bueno tener una solución tan simple como vector de.

¿Fue útil?

Solución

Tal vez se puede pasar algo así como "asas" para la lista / iteradores deque? Estos tipos de mango serían opacas y declarada en un archivo de cabecera que le enviará a los usuarios. Internamente, lo que se necesita para asignar los valores de identificador para la lista / iteradores deque. Básicamente, el usuario podría escribir código como:

ListHandle lhi = GetListDataBegin();
const ListHandle lhe = GetListDataEnd();

while (lhi != lhe)
{
  int value = GetListItem(lhi);
  ...
  lhi = GetNextListItem(lhi);
}

Otros consejos

Puede pasar objetos entre stl DLL y apoyar diferentes compiladores si se tiene cuidado en que se ejemplariza cada tipo STL. Es necesario algunas macros inteligentes "dllexport" - utilizo el siguiente conjunto para apoyar con éxito VC y gcc

.
#ifdef WIN32
#ifdef MYDLLLIB_EXPORTS      // DLL export macros
#define MYDLLLIB_API __declspec(dllexport)
#define MYDLLLIB_TEMPLATE
#else
#define MYDLLLIB_API __declspec(dllimport)
#define MYDLLLIB_TEMPLATE extern
#endif
#else                       // Not windows --- probably *nix/bsd
#define MYDLLLIB_API
#ifdef MYDLLLIB_EXPORTS
#define MYDLLLIB_TEMPLATE
#else
#define MYDLLLIB_TEMPLATE extern
#endif
#endif // WIN32

Al compilar el archivo DLL, definir MYDLLLIB_EXPORTS. En la DLL a continuación, puede crear una instancia de cada tipo STL que desea utilizar, por ejemplo, listas o vectores de cadenas

MYDLLLIB_TEMPLATE template class MYDLLLIB_API std::vector<std::string>;
MYDLLLIB_TEMPLATE template class MYDLLLIB_API std::list<std::string>;

Los consumidores de la DLL (que no tienen definidos MYDLLLIB_EXPORTS) verán entonces

extern template class __declspec(dllimport) std::vector<std::string>;

y utilizando un código binario exportada desde el archivo DLL en lugar de crear instancias de su cuenta.

  

la interfaz entre la aplicación   y DLL, básicamente, tiene que seguir siendo   llanura de edad-datos.

No necesariamente. Usted tiene que asegurarse de que se utiliza la misma versión del compilador. Además, la configuración de creación que afectan a la disposición de los objetos STL es exactamente la misma entre la DLL y la aplicación.

Si se va a liberar el DLL a cabo en el medio natural, usted tiene razón para estar preocupados con la exposición de STL través de los límites del DLL. Sin embargo, si todo está bajo su control y puramente interna (o si puede hacer cumplir rígidamente tercera parte la configuración de creación / compilador) que debe estar bien.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top