C ++带有模板的共享库:未定义的符号错误

C ++带有模板的共享库:未定义的符号错误

问题描述:

我尝试使用模板类链接到共享库,但它给我未定义的符号错误。我已将问题集中到大约20行代码。

I'm trying to link to a shared library with a template class, but it is giving me "undefined symbols" errors. I've condensed the problem to about 20 lines of code.

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 中的'template',并且只用'int' 。此外,如果我只是复制&粘贴模板类代码到 main.cpp ,并且不链接到共享库,一切都一样好。

If I remove the 'template' stuff in shared.h/cpp, and replace them with just 'int', everything works fine. Also, if I just copy&paste the template class code right into main.cpp, and don't link to the shared library, everything works as well.

如何获得这样的模板类通过共享库工作?

How can I get a template class like this to work through a shared library?

MacOS 10.5 with GCC 4.0.1。

I'm using MacOS 10.5 with GCC 4.0.1.

除了其他答案,你可以显式实例化模板类。这只有在事先知道模板参数可以假定的类型时才有用。

In addition to the other answers, you can explicitly instantiate template classes. This is only useful if you know beforehand what types the template parameters may assume. You instantiate the template with all these types in the library.

要编译的示例,只需将以下内容添加到 shared.cpp 的末尾即可>:

For your example to compile, just add the following to the end of shared.cpp:

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

使用Type = int实例化模板,并将实例化的代码放在共享库中。

This instantiates the template with Type=int and places the instantiated code in the shared library. Add as many explicit instantiations as you need, for all the types you need.

再次,如果你想能够使用任何类型的参数来实例化模板,那么,您必须将定义添加到头文件,以便编译器知道模板的源代码,在其他编译单元实例化时。

Again, if you want to be able to instantiate the template with any arbitrary Type parameter, then you must add the definitions to the header file, so that the compiler knows the source code of the template when instantiating it in other compilation units.