Estoy usando VS2008 en win7 y g++ 4.7 en CentOS 18. El problema es que sólo se ve en Windows cuando se utiliza de forma dinámica de la biblioteca compartida. Cuando me convertirlo biblioteca estática el programa enlaces bien.

Entiendo que en la biblioteca compartida de la plantilla de funciones/clase debe ser definido en el archivo de encabezado o de la plantilla de la creación de instancias de los tipos de plantilla(parámetros) debe ser proporcionada a través de la unidad de compilación. Yo he elegido la última opción. Lo he hecho antes, me fui a través de

¿Por qué las plantillas sólo se implementa en el archivo de encabezado?

C++ Biblioteca Compartida con Plantillas: Undefined symbols de error

Pero no puedo averiguar por qué en windows tan pronto como puedo convertir la biblioteca dll que no se pudo resolver en símbolos:
error LNK2019: símbolo externo sin resolver «void __cdecl HelpingRegistration(doble)» ([email protected]@@[email protected]) que se hace referencia en función de _main

En Windows funciona bien con la biblioteca estática.
En Linux dinámica y compartida de la biblioteca de obras.

//Static library
//Library header
#ifndef _TEMPLATED_STATIC_LIB_
#define _TEMPLATED_STATIC_LIB_

#include <iostream>
#include <string>
#include "Export.h"

template<typename T>
class EXPORT TemplatedStaticLib
{
public:
    TemplatedStaticLib(){};
    ~TemplatedStaticLib(){};

    void print(T t);

};

template<typename T>
EXPORT void HelpingRegistration(T);

#endif

//biblioteca .cpp

#include "TemplatedStaticLib.h"
#include <typeinfo>


template<typename T>
void TemplatedStaticLib<T>::print(T t)
{
    std::cout << "Templated Print: "<< t<< " type:: "  << typeid(t).name() << std::endl;
}

//Class Template explicit instantiation
template class TemplatedStaticLib<double>;
template class TemplatedStaticLib<std::string>;

template<typename T>
void  HelpingRegistration(T t)
{
    std::cout << "Function Templated Print: "  << t << " type: " << typeid(t).name() << std::endl;
       //return t;
}

//function template explicit instantiation
template void HelpingRegistration<>( double );
template void HelpingRegistration<>( std::string );

//Símbolo de Windows exportador

//.h

#ifndef STATIC_LIB_EXPORT
#define STATIC_LIB_EXPORT

#if !defined WIN32
    #define EXPORT
#elif defined LIB_EXPORTS
    #define EXPORT __declspec(dllexport)
#else
    #define EXPORT __declspec(dllimport)
#endif

//STATIC_LIB_EXPORT
#endif

//usuario de la biblioteca .cpp

#include <TemplatedStaticLib/TemplatedStaticLib.h>

#include<string>

int main(int argc, char* argv[])
{
    double aDouble = 3.9;
    TemplatedStaticLib<double> double_test; 
    double_test.print(aDouble);

    std::string aString = "James";
    TemplatedStaticLib<std::string> string_test; 
    string_test.print(aString);

    HelpingRegistration(aDouble);
    HelpingRegistration(aString);


    return 0;
}
  • Hay literaria miles de duplicados a este. No se puede dividir plantilla de clases en el encabezado del archivo de origen y, como de costumbre, todo tiene que estar en las cabeceras.
  • posibles duplicados de ¿por Qué las plantillas sólo se implementa en el archivo de encabezado?
  • Pileborg que sin duda puede ser realizado como se muestra en la respuesta proporcionan en la pregunta stackoverflow.com/questions/495021/… y estoy haciendo esto demasiado solo en la dll de Windows que se produzca issuee pleae leer la pregunta completa la primera
  • el enlace que se proporciona no explica por qué sólo en archivo dll compartido que está causando el problema
  • No explica por qué es «sólo» causas de los problemas en una DLL, pero no explica por qué causa los problemas. Usted debe estar preguntándose por qué algo roto parece trabajar en una biblioteca estática. En realidad, no deberías estar intentando utilizar el código roto.
  • Me fui a través de los enlaces que proporcionan y que indican si una explícita la creación de instancias se proporciona, se debe trabajar y que lo hace con el compilador g++. Está bien si usted no sabe vs2008 respuesta específica, pero ¿por qué marca hacia abajo, otras personas pueden saber la respuesta.

InformationsquelleAutor jazaman | 2013-07-08

3 Comentarios

  1. 4

    Creo que usted necesita para exportar las especializaciones. ¿Has probado esta en su .archivo cpp:

    template class EXPORT TemplatedStaticLib<double>;
    template class EXPORT TemplatedStaticLib<std::string>;

    y prácticamente el mismo en su encabezado:

    template class EXPORT TemplateStaticLib<double>;
    template class EXPORT TemplateStaticLib<std::string>;

    Me pensar que va a trabajar con su EXPORTACIÓN macro (suponiendo que el .archivo cpp ver __declspec(dllexport) y el encabezado ve __declspec(dllimport)). Admito que no soy un experto con Windows’ __declspec.

    Tengo que admitir que me llamó la respuesta de esta otra respuesta en el intarwebs: http://social.msdn.microsoft.com/Forums/vstudio/en-US/4fd49664-e28e-4f23-b1eb-b669d35ad264/function-template-instantation-export-from-dll (desplácese a la parte inferior para Franjo555 la versión final.)

    • La plantilla de clase símbolos están presentes. Pero la función libre de la plantilla de símbolos que faltan. He utilizado dumpbin /EXPORTAR a ver los símbolos. Me funcionó la solución que voy a publicar a continuación.
    • Su idea era correcta, aunque yo necesarios para la exportación de la plantilla de función casos … gracias
    • Usted no necesita __declspec(dllimport) los métodos, suponiendo que la clase en sí es exportado / importado.
    • Tenga en cuenta que EXPORT aquí debe ser después de class, no antes. Si es antes, ninguna de las exportaciones se generan.
    • Por favor, tenga en cuenta que la exportación de especialización de la te de la plantilla de clase en el .archivo cpp debe aparecer antes cualquier método especializado, no después. Probado en VS2017.
  2. 2

    Resolví el problema. En windows plantilla de clase y la función de la plantilla se exportan de manera diferente y no hay una lectura interesante en la red.

    VS compiladores de las exportaciones de la plantilla de clase símbolos si la plantilla de clase se crea una instancia en la unidad de traducción (.cpp).

    Sin embargo, en el caso de la plantilla de función, la palabra clave » __declspec(dllexport)’ debe estar presente de forma explícita para los símbolos que se presentan en la dinámica de la biblioteca.

    e.g

    template EXPORT void HelpingRegistration<double>( double );
    //EXPORT is defined as __declspec(dllexport) 

    Es sólo otro caso donde VS decidir las cosas de manera diferente. No es una lectura interesante aquí:
    http://www.codesynthesis.com/~boris/blog/2010/01/18/dll-exportación-cxx-plantillas/

  3. 0

    Creo que esto es porque el compilador genera código especializado para la clase de plantilla cuando la clase de plantilla que se utilizó por primera vez con parámetros específicos. Desde que el compilador utiliza sólo la incluye los archivos de cabecera (.h) cuando se esta cumpliendo una unidad de compilación (.archivos cpp) todas las tmplate código debe estar disponible en .h archivos. Puede exportar especializados en clases de plantilla desde un archivo dll, pero no la plantilla de las mismas clases.

Dejar respuesta

Please enter your comment!
Please enter your name here