C ++共享库使用模板:未定义的符号错误C ++共享库使用模板:未定义的符号错误(C++ Share

2019-05-13 14:19发布

我试图链接到一个模板类的共享库,但它给我“未定义的符号”错误。 我已经凝结的问题约20行代码。

shared.h

template <class Type> class myclass {
  Type x;
public:
  myclass() { x=0; }
  void setx(Type y);
  Type  getx();
};

shared.cpp

#include "shared.h"
template <class Type> void myclass<Type>::setx(Type y) { x = y; }
template <class Type> Type myclass<Type>::getx() { return x; }

main.cpp中

#include <iostream>
#include "shared.h"
using namespace std;

int main(int argc, char *argv[]) {
   myclass<int> m;
   cout << m.getx() << endl;
   m.setx(10);
   cout << m.getx() << endl;
   return 0;
}

这是我的编译库文件:

g++ -fPIC -c shared.cpp -o shared.o
g++ -dynamiclib -Wl,-dylib_install_name -Wl,libshared.dylib -o libshared.dylib shared.o

和主要程序:

g++ -c main.cpp
g++ -o main  main.o -L. -lshared

只有得到以下错误:

Undefined symbols:
"myclass<int>::getx()", referenced from:
  _main in main.o
  _main in main.o
"myclass<int>::setx(int)", referenced from:
  _main in main.o

如果我删除了“模板”的东西shared.h/cpp ,并与刚刚“诠释”取代他们,一切工作正常。 另外,如果我只是复制及模板类代码粘贴到main.cpp ,不链接到共享库,一切工作为好。

我怎样才能得到一个模板类,像这样通过一个共享库的工作?

我使用的MacOS 10.5 GCC 4.0.1。

Answer 1:

除了其他的答案,你可以明确地实例化的模板类。 如果你事先知道模板参数可以承担什么类型的这是唯一有用的。 您实例化所有这些类型库中的模板。

为了您的例子编译,只需添加以下shared.cpp的结尾:

// Instantiate myclass for the supported template type parameters
template class myclass<int>;
template class myclass<long>;

这个实例与类型= INT模板,并将实例化代码的共享库。 因为你需要,你需要的各类添加尽可能多的明确的实例。

同样,如果你希望能够与任意类型的参数来实例化的模板,然后你必须定义添加到该头文件,以便在其他编译单元实例化时,编译器知道模板的源代码。



Answer 2:

模板函数定义必须驻留在头文件。 从shared.cpp移动定义,以shared.h。

所以,你不能编译这一个共享库,然后链接到它。 这是行不通的那样。



Answer 3:

您需要包括在头文件的模板类的实现也是如此。 这是在C ++模板的约束。 因此,无论从包括主(#包括)shared.cpp或刚刚从shared.cpp移动代码shared.h



Answer 4:

编译器必须看到模板的全部代码,因此它可以生成你想要使用的实际类型相应的代码。 所以,你应该把所有的代码在你的.h。 文件。



文章来源: C++ Shared Library with Templates: Undefined symbols error