Unused template functions in shared library
I have a template function in a shared library written in C++(the function is not called anywhere in the library, so it shouldn't be generated, am i wrong?) [g++, Linux]
I try to use this template function in the application but compiler gives link error.I searched the function using objdump but I c开发者_Python百科an not see the function in the .so Is there a way to solve this problem?
Template functions belong to library headers, they aren't compiled in the DLL shared library. So, move all template functions into a header, and include that header in your application.
The easiest way is just to move all template code into the header file (as described in other answers)
BUT this is not the only solution.
Template are not actual functions.
A template becomes a function when there is an instanciation of the function. This can be done implicitly or explicitly. Any time the function is used there is an implicit instanciation. But you can also explicitly instanciate the template function.
So you should be able to link against any instanciated version of the template function in your share lib.
Header file so we obey the one definition rule.
// tt.h
template<typename T>
int doStuff(Tconst &t);
Source file:
// tt.cpp
#include "tt.h"
template<typename T>
int doStuff(Tconst &t)
{
return 4;
}
void plop()
{
int x = 6;
// implicit instanciation of doStuff<int>(int const&);
doStuff(x);
}
// explicit instanciation of template
template int doStuff<float>(float const&);
If I compiled the above into a shared lib.
Then there would be two doStuff() methods that are available.
- doStuff<int>(int const&) // Implicit instanciation
- doStuff<float>(float const&) // explit instanciation
g++ -shared -o tt.so tt.cpp
Now if we have a seprate file that we link against the shared lib:
// main.cpp
#include "tt.h"
int main()
{
doStuff(5); // doStuff<int>()
doStuff(6.0f); // doStuff<float>()
}
g++ main.cpp t.so
Compiles fine even though main can not see any of the template code.
Templates are hard to implement by compiler developers, and thus, most C++ compilers actually require you to put template code in header files, even complete class implementations (there are some exceptions and tricks to avoid this though).
For your case, all you need to do is move your function template to a header file (probably with other function templates) and import that when you need it.
Hope that helps.
The function you want to use needs to be instantiated somewhere, either in your library or in your code. Your compiler should be generating the instantiation for you in your program code unless the prototype was declared extern. It sounds like you want to explicitly instantiate the function in your library. In one of the source files in your library, you can just add a line like:
template return_type function_name(param_type,param_type);
and the code for the function should be explicitly generated.
More on explicit instantiation: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/explicit_instantiation.htm
I found myself in the same situation some time ago, so I investigated on this. Basically templates do not produce any object code, they are simply a definition for the compiler. When you instantiate a object like std::list<Foo> l
the compiler will produce both the instance and the specialized code for a list of Foo objects.
This leads to two consequences:
- It's not possible to write template-classes code into a dedicated .cpp file (like you would do for a normal module), since you don't know in advance which data types you'll need to instanciate;
- Two .cpp files both using
std::list<Foo>
as data type will produce a copy of the same executable code.
The second point makes things difficult during linking phase, since the linker is supposed to deal with double definitions. A possible linking strategy would be keeping a copy for each object code. A smarter linker may try to optimize things, but this gives a great complexity.
I guess this is why gcc takes so long to compile C++, while it's far more quick with C.
精彩评论