IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Template et probleme au linkage (seulement windows)


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Juin 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Par défaut Template et probleme au linkage (seulement windows)
    Bonjour,


    J'ai un probleme avec l'utilisation de templates quand je suis au moment du linkage.

    ------------------------------------

    Dans une librairie A je creer une templates:

    include/libA/paramsnodevec.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
     
    template <typename _Tp>
    class X7S_CX_DLL ParamsNodeVec: public ParamsNode
    {
    public:
    	ParamsNodeVec(ParamsNode *parent, const std::string& name, int ID=X7S_ANY_ID)
    	:ParamsNode(parent,name, X7S_ANY_TYPE, ID) {};
    	virtual ~ParamsNodeVec() { deleteAll(); };
     
     
    	bool append(_Tp* obj)
    	{
    		bool isok=true;
    		if(obj)
    		{
    			//Check that it has the same parent
    			if(((ParamsNode*)obj)->getParent() != this)
    			{
    				//Otherwise add it to the XmlList
    				isok=this->addAsChild(obj);
    			}
    			else
    			{
    				//Otherwise check for duplicate (in the list)
    				for(int i=0;i<length();i++)
    				{
    					if(obj==m_vec[i]) isok=false;
    				}
    			}
    			if(isok) m_vec.push_back(obj);
    		}
    		return isok;
    	}
     
     
    	const _Tp* at(int index) const
    							{
    		if(0 <= index  && index < length())
    			return m_vec.at(index);
    		else
    		{
    			return NULL;
    		}
    							}
     
     
    	_Tp* at(int index)
    							{
    		if(0 <= index  && index < length())
    			return m_vec.at(index);
    		else
    		{
    			return NULL;
    		}
    							}
     
    	const std::vector<_Tp*> vec() { return m_vec; }
     
     
    	_Tp* remove(int index)
    	{
    		_Tp* ret=NULL;
    		if(0<= index && index < length())
    		{
    			ret=m_vec[index];
    			m_vec.erase(m_vec.begin()+index);
    		}
    		return ret;
    	}
     
     
    	bool erase(int index)
    	{
    		_Tp* tmp = this->remove(index);
    		if(tmp)
    		{
    			delete tmp;
    			return true;
    		}
    		return false;
    	}
     
     
    	size_t size() const { return m_vec.size(); }
    	int length() const { return (int)m_vec.size(); }
     
     
    	/**
             * @brief Generic method to create a child giving all the information
             *
             * This method is one called by the XML library
             */
    	bool createChild(const std::string& name, int type, int id, int pos)
    	{
    		bool ret=false;
    		if(name.compare(_Tp::nodeName())==0)
    		{
    			//Delete all other child if we are the first one.
    			if(pos==ParamsNode::First) this->deleteAll();
     
    			//Call the new function to create children
    			_Tp *tmp = this->newChild(type);
    			if(tmp)
    			{
    				ret = this->append(tmp);
    				if(ret && id != X7S_ANY_ID)
    				{
    					ret = this->setChildID(tmp,id);
    					if(ret==false)
    					{
    						_X7S_DEBUG_CL_M("createChild()",ECAT_CORE,ELVL_INF,Err_Duplicate,"Can not append %s to %s because ID %d already exist",
    								tmp->name().c_str(),this->name().c_str(),id);
    						this->erase(size()-1);
    					}
     
    				}
    			}
    		}
    		return ret;
    	}
     
     
    protected:
     
    	void deleteAll()
    	{
     
    		//Copy all the value in a temporary vector
    		std::vector<_Tp*> tmpVec=m_vec;
     
    		//Clear the vector (not usable in other thread)
    		m_vec.clear();
     
    		//Delete the value one by one from the temporary vector.
    		for(size_t i=0;i<tmpVec.size();i++)
    		{
    			X7S_DELETE_PTR(tmpVec[i]);
    		}
    	}
     
    	/**
             * @brief Virtual method to create a child
             *
             * This method must be overloaded in the class that will implement it.
             * The child created can be with a NULL parent, because we will add it.
             *
             * @param type
             */
    	virtual _Tp* newChild(int type)=0;
     
    protected:
    	std::vector<_Tp* > m_vec;
     
    };
    Dans une librarie B (qui depend de A) je creer les fichiers suivants:

    libB/shapes.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
     
    #include <core/paramsnodevec.h>
    class Shape; //!< Prototype
     
    class X7S_CVPP_DLL Shapes: public ParamsNodeVec<Shape>
    {
    public:
    	Shapes(ParamsNode *parent, const cv::Size& reso);
    	virtual ~Shapes();
    	void draw(cv::Mat& im) const;
     
    	const cv::Size& resolution() const { return m_reso; }
     
    protected:
    	Shape* newChild(int type);
    	void initParams() {};
     
    protected:
    	cv::Size		m_reso;
    };
    libB/shapes.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
     
    Shapes::Shapes(ParamsNode *parent, const cv::Size& reso)
    :ParamsNodeVec<Shape>(parent,"shapes"), m_reso(reso)
     {
     
     }
     
    Shapes::~Shapes()
    {
     
    }
     
     
    void Shapes::draw(cv::Mat& img) const
    {
    	Shape *shape;
    	for(size_t i=0;i<m_vec.size();i++)
    	{
    		shape=m_vec[i];
    		if(shape) shape->draw(img);
    	}
    }
     
     
    Shape* Shapes::newChild(int type)
    {
    	Shape *s= Shape::create(type);
    	if(s) s->setResolution(m_reso);
    	return s;
    }

    ------------------------------------

    Avec MinGW j'ai les erreurs suivantes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Linking CXX shared library ..\..\..\bin\libx7scvpp.dll
    cd C:\Users\Ben\project\builds\CvS400\ecVGA\x7s\modules\cvpp && "C:\Program Files\CMake 2.8\bin\cmake.exe" -E cmake_link_script CMakeFiles\x7scvpp.dir\link.txt --verbose=1
    C:\MinGW\bin\g++.exe    -shared -o ..\..\..\bin\libx7scvpp.dll -Wl,--out-implib,..\..\..\lib\libx7scvpp.dll.a -Wl,--major-image-version,1,--minor-image-version,1 -Wl,@CMakeFiles\x7scvpp.dir\objects1.rsp ..\..\..\lib\libx7score.dll.a ..\..\..\lib\libx7scv.dll.a C:\Libs\OpenCV\installed\lib\libcxcore210d.dll.a C:\Libs\OpenCV\installed\lib\libcv210d.dll.a C:\Libs\OpenCV\installed\lib\libml210d.dll.a C:\Libs\OpenCV\installed\lib\libhighgui210d.dll.a C:\Libs\OpenCV\installed\lib\libcvaux210d.dll.a ..\..\..\3rdparty\lib\liblibjpeg.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 
    CMakeFiles/x7scvpp.dir/src/shape.cpp.obj:shape.cpp:(.text$_ZN3x7s13ParamsNodeVecINS_5ShapeEEC2EPNS_10ParamsNodeERKSsi[x7s::ParamsNodeVec<x7s::Shape>::ParamsNodeVec(x7s::ParamsNode*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)]+0x67): undefined reference to `_imp___ZTVN3x7s13ParamsNodeVecINS_5ShapeEEE'
    CMakeFiles/x7scvpp.dir/src/shape.cpp.obj:shape.cpp:(.text$_ZN3x7s13ParamsNodeVecINS_5ShapeEEC1EPNS_10ParamsNodeERKSsi[x7s::ParamsNodeVec<x7s::Shape>::ParamsNodeVec(x7s::ParamsNode*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)]+0x67): undefined reference to `_imp___ZTVN3x7s13ParamsNodeVecINS_5ShapeEEE'
    CMakeFiles/x7scvpp.dir/src/shape.cpp.obj:shape.cpp:(.text$_ZN3x7s13ParamsNodeVecINS_5ShapeEED2Ev[x7s::ParamsNodeVec<x7s::Shape>::~ParamsNodeVec()]+0x36): undefined reference to `_imp___ZTVN3x7s13ParamsNodeVecINS_5ShapeEEE'
    CMakeFiles/x7scvpp.dir/src/shape.cpp.obj:shape.cpp:(.text$_ZN3x7s13ParamsNodeVecINS_5ShapeEED1Ev[x7s::ParamsNodeVec<x7s::Shape>::~ParamsNodeVec()]+0x36): undefined reference to `_imp___ZTVN3x7s13ParamsNodeVecINS_5ShapeEEE'
    CMakeFiles/x7scvpp.dir/src/shape.cpp.obj:shape.cpp:(.text$_ZN3x7s13ParamsNodeVecINS_5ShapeEED0Ev[x7s::ParamsNodeVec<x7s::Shape>::~ParamsNodeVec()]+0x36): undefined reference to `_imp___ZTVN3x7s13ParamsNodeVecINS_5ShapeEEE'
    Avec MVC2008 j'obtient comme message:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    1>   Creating library C:\Users\Ben\project\builds\CvS400\vc9VGA-2\lib\Debug\x7scvpp.lib and object C:\Users\Ben\project\builds\CvS400\vc9VGA-2\lib\Debug\x7scvpp.exp
    1>shape.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall x7s::ParamsNodeVec<class x7s::Shape>::~ParamsNodeVec<class x7s::Shape>(void)" (__imp_??1?$ParamsNodeVec@VShape@x7s@@@x7s@@UAE@XZ) referenced in function "public: virtual __thiscall x7s::Shapes::~Shapes(void)" (??1Shapes@x7s@@UAE@XZ)
    1>shape.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall x7s::ParamsNodeVec<class x7s::Shape>::ParamsNodeVec<class x7s::Shape>(class x7s::ParamsNodeVec<class x7s::Shape> const &)" (__imp_??0?$ParamsNodeVec@VShape@x7s@@@x7s@@QAE@ABV01@@Z) referenced in function "public: __thiscall x7s::Shapes::Shapes(class x7s::Shapes const &)" (??0Shapes@x7s@@QAE@ABV01@@Z)
    1>shape.obj : error LNK2001: unresolved external symbol "public: virtual bool __thiscall x7s::ParamsNodeVec<class x7s::Shape>::createChild(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,int,int,int)" (?createChild@?$ParamsNodeVec@VShape@x7s@@@x7s@@UAE_NABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HHH@Z)
    1>shape.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class x7s::ParamsNodeVec<class x7s::Shape> & __thiscall x7s::ParamsNodeVec<class x7s::Shape>::operator=(class x7s::ParamsNodeVec<class x7s::Shape> const &)" (__imp_??4?$ParamsNodeVec@VShape@x7s@@@x7s@@QAEAAV01@ABV01@@Z) referenced in function "public: class x7s::Shapes & __thiscall x7s::Shapes::operator=(class x7s::Shapes const &)" (??4Shapes@x7s@@QAEAAV01@ABV01@@Z)
    1>shape.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall x7s::ParamsNodeVec<class x7s::Shape>::ParamsNodeVec<class x7s::Shape>(class x7s::ParamsNode *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,int)" (__imp_??0?$ParamsNodeVec@VShape@x7s@@@x7s@@QAE@PAVParamsNode@1@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z) referenced in function "public: __thiscall x7s::Shapes::Shapes(class x7s::ParamsNode *,class cv::Size_<int> const &)" (??0Shapes@x7s@@QAE@PAVParamsNode@1@ABV?$Size_@H@cv@@@Z)
    1>shape.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: bool __thiscall x7s::ParamsNodeVec<class x7s::Shape>::append(class x7s::Shape *)" (__imp_?append@?$ParamsNodeVec@VShape@x7s@@@x7s@@QAE_NPAVShape@2@@Z) referenced in function "public: __thiscall x7s::Shape::Shape(int,class x7s::Shapes *)" (??0Shape@x7s@@QAE@HPAVShapes@1@@Z)
    1>C:\Users\Ben\project\builds\CvS400\vc9VGA-2\bin\Debug\x7scvpp.dll : fatal error LNK1120: 6 unresolved externals
    1>Build log was saved at "file://c:\Users\Ben\project\builds\CvS400\vc9VGA-2\x7s\modules\cvpp\x7scvpp.dir\Debug\BuildLog.htm"

    Sous linux tout compil correctement.

    --------------------------------------


    J'ai regarder dans plusieurs FAQ et je ne comprend pas ou est l'erreur car j'ai la declaration complete dans mon fichier .h

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 482
    Par défaut
    Je sais par pour le reste mais pour MVC2008, il y a utilisation de dll.
    Il y a une méthode, "createChild", n'est pas taggué comme venant d'une dll.
    Un template ne génère pas de code tant qu'il n'a pas été instancié avec des types concrets.
    L'instanciation "ParamsNodeVec<class x7s::Shape>" a-t-elle été faites via une globale dans la dll ?
    Utilisez-vous le fichier lib de la dll pour l'édition de lien ?

    En général, les templates et les dll ne font pas très bon ménage.

  3. #3
    Membre confirmé
    Inscrit en
    Juin 2003
    Messages
    223
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Juin 2003
    Messages : 223
    Par défaut
    En fait je viens de trouver la solution ... c’était tres stupide comme erreur.

    Pour pouvoir compiler de maniere portable j'ai les defines suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #if (defined WIN32 || defined WIN64 || defined _WIN64)
    #define X7S_EXPORT __declspec(dllexport)	//!< Export to a DLL (under windows)
    #define X7S_IMPORT __declspec(dllimport)	//!< Import from a DLL (under windows)
    #else
    #define X7S_EXPORT
    #define X7S_IMPORT
    #endif
     
    #ifdef x7score_EXPORTS
    	#define X7S_CX_DLL X7S_EXPORT
    #else
    	#define X7S_CX_DLL X7S_IMPORT
    #endif
    Le problème c'est que l'on ne peut pas importer un template car on crée l'instance au même moment ou l'on définit le template.
    D'ou mes erreurs:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    error LNK2019: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall ....
    Donc pour un template on doit toujours utiliser le mot clefs dllexport (import ne sert a rien)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MFC]+[dll] probleme au linkage
    Par BainE dans le forum MFC
    Réponses: 3
    Dernier message: 22/06/2005, 12h04
  2. Probleme de démarrage sous windows 98
    Par Le Pharaon dans le forum Windows 2000/Me/98/95
    Réponses: 14
    Dernier message: 03/05/2005, 14h05
  3. Probleme de deplacement de windows.
    Par Clad3 dans le forum OpenGL
    Réponses: 3
    Dernier message: 07/12/2004, 00h51
  4. [MFC ]Probleme de linkage d'une dll
    Par Lysis dans le forum MFC
    Réponses: 9
    Dernier message: 22/01/2004, 14h51
  5. Probleme de linkage avec DirectDraw7 sous BC++ 5.02
    Par bobtorn dans le forum DirectX
    Réponses: 3
    Dernier message: 07/10/2003, 20h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo