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
Dans une librarie B (qui depend de A) je creer les fichiers suivants:
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; };
libB/shapes.h
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 #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; };
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:
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 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'
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
Partager