LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Problem creating shared lib containing templates. Help...... (https://www.linuxquestions.org/questions/programming-9/problem-creating-shared-lib-containing-templates-help-684203/)

linuxmthomson 11-17-2008 08:52 PM

Problem creating shared lib containing templates. Help......
 
hey guys, any help would be appreciated as this is driving me nuts.

I am basically trying to create a shared lib that contains templates. This code used to work on solaris under Sunwspro but when i try and compile under RH linux CC:

Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.2 20071124 (Red Hat 4.1.2-42)


It doesn't work.

Here is my code ( any help would be greatly appreciated )

//AClass.h
#include <string>

using namespace std;

template <class T>
class AClass
{
public:
AClass(){};
~AClass(){};
T getName();
private:
T name;


};

//AClass.cc
#include "AClass.h"

template <class T>

T AClass<T>::getName()
{
return name;
}

//TestA.cc
#include "AClass.h"
int main()
{
AClass<string> a;
a.getName();
return 0;

}


/usr/bin/cc -m32 -c -o AClass.o AClass.cc - COMPILES OK

/usr/bin/cc -shared -o libTest.so AClass.o -g -m32 -lstdc++ - CREATES SHARED LIB

Here is the nm map for the shared lib. Interestingly enough, no reference to getName() ??

nm libTest.so
00000000000013fc a _DYNAMIC
00000000000014d0 a _GLOBAL_OFFSET_TABLE_
w _Jv_RegisterClasses
00000000000013e8 d __CTOR_END__
00000000000013e4 d __CTOR_LIST__
00000000000013f0 d __DTOR_END__
00000000000013ec d __DTOR_LIST__
00000000000003e0 r __FRAME_END__
00000000000013f4 d __JCR_END__
00000000000013f4 d __JCR_LIST__
00000000000014e4 A __bss_start
w __cxa_finalize@@GLIBC_2.1.3
0000000000000390 t __do_global_ctors_aux
00000000000002d0 t __do_global_dtors_aux
00000000000013f8 d __dso_handle
w __gmon_start__
0000000000000387 t __i686.get_pc_thunk.bx
00000000000014e4 A _edata
00000000000014ec A _end
00000000000003c4 T _fini
0000000000000258 T _init
00000000000002a0 t call_gmon_start
00000000000014e8 b completed.5803
00000000000014e4 b dtor_idx.5805
0000000000000350 t frame_dummy



/usr/bin/cc -g -m32 -Wno-deprecated -I. -L. -l Test -lstdc++ TestA.cc -o TestA.exe

This fails with:

/usr/bin/cc -g -m32 -Wno-deprecated -I. -L. -l Test -lstdc++ TestA.cc -o TestA.exe
/var/tmp/cccRx1dy.o: In function `main':
/home/mark/workspace/ITSMarketInfo/src/cpp/Sandbox/TestA.cc:5: undefined reference to `AClass<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::getName()'
collect2: ld returned 1 exit status

ta0kira 11-17-2008 09:12 PM

What you're doing is not possible because templates aren't classes, functions, or data; they don't exist unless they're used. That means T AClass<T>::getName() doesn't exist until it's used, and it's never used in the context of the compilation of AClass.cc. For that reason, T AClass<T>::getName() must be available in the context of every parameter T being used, otherwise the function is never compiled. In other words, main.cc needs to include the file that defines T AClass<T>::getName(). Normally this is done by having the header include its own source, or by putting them both in the same file.
ta0kira

linuxmthomson 11-19-2008 01:03 AM

Thanks, that worked a treat.

Interestingly enough my old implementation compiles / links and runs on Solaris. I do remember something about the Solaris Sunwspro compiler generating all of the template implemenations for you.


All times are GMT -5. The time now is 09:03 PM.