C++ Templates & shared-libraries

Programming, for all ages and all languages.
Post Reply
User avatar
bluecode
Member
Member
Posts: 202
Joined: Wed Nov 17, 2004 12:00 am
Location: Germany
Contact:

C++ Templates & shared-libraries

Post by bluecode »

hi,

is there a way to compile the most common templates instances into a shared library (e.g. vector<void*,..>) without using the nearly-nowhere-implemented 'export' keyword? It would be awesome if I could just stuff most of the STL in my OS in a shared library...

btw. why is the 'export' keyword not implemented? I read somewhere that it breaks the existing toolchains, but why?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

I encountered this problem when trying to include templated utility classes (such as LinkedList and OrderedArray) from my kernel to user programs (more specifically the newlib glue functions).

What I did was to write a function in my kernel that creates templated classes and calls functions on them, e.g.

Code: Select all

void registerSharedTemplates()
{
  vector<void *, ...> v;
  v.push_back((void*)5);
}
Then in my kernel init function adding a:

Code: Select all

if (false) registerSharedTemplates();
Because the function is defined (and referenced), it appears in the object file and the linker adds it, but the compiler will notice the if (false) and optimise out the call. So the templated calls end up in your .so with no performance penalty.

It's a bit of a hack but I couldnt' get it to work otherwise.

My func, from my kernel:

Code: Select all

void importSymbols()
{
  Directory d(NULL,NULL);
  d.mount(NULL);
  CharDevice c(NULL, NULL);
  File::ImplDefined impl;
  d.assignPointers(NULL,NULL,NULL,impl);
  Process *p=processManager.getProcess();
  p->getCtty();
  p->getMessageSender();
}
...
if (false)
  {
    importSymbols();
  }
User avatar
bluecode
Member
Member
Posts: 202
Joined: Wed Nov 17, 2004 12:00 am
Location: Germany
Contact:

Post by bluecode »

Thanks for the fast reply. Well it sounds like a hack, but I honestly didn't expect anything else :)
Let's assume I have my favorite template instanciations (say alls functions of vector<void*,...>) in a shared-library. When I now compile a normal application the compiler does not know that the code for the template instance is already generated so the generated code for e.g. vector<void*,...>::push_back(...) will end up in the elf object file (myapp.o). When I now link my application against the shared-library, will the linker see that the symbol vector<void*,...>::push_back(...) is defined in myapp.o and in mylib.so? Does the linker than discard the symbol from myapp.o and just use the one from mylib.so? Did you verify that?

edit: btw. you could provide a link in your signature... I am too lazy to copy & paste :D
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

So don't provide the implementation of your templated class in normal applications. Just give them the declarations and leave the linker to find everything.

And there's nothing there apart from a source tree at the moment, so theres no need for a link ;)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: C++ Templates & shared-libraries

Post by Solar »

bluecode wrote:I read somewhere that it breaks the existing toolchains, but why?
Not to my knowledge. AFAIK, the compiler vendors take the stance that "nobody asks for it so why implement it", comfortably ignoring the fact that the not-asking might be because few even know about export - which does not mean it wouldn't be beneficial for their work.

It does require quite some additional bookkeeping by the compiler though. IMHO, the compiler vendors, including the GNU people, are simply shirking the effort.
Every good solution is obvious once you've found it.
User avatar
bluecode
Member
Member
Posts: 202
Joined: Wed Nov 17, 2004 12:00 am
Location: Germany
Contact:

Post by bluecode »

JamesM wrote:So don't provide the implementation of your templated class in normal applications. Just give them the declarations and leave the linker to find everything.
Your right... somehow I was thinking that you have to provide the definition for all your template foobar. :roll:

Thank you Solar and JamesM!
User avatar
bluecode
Member
Member
Posts: 202
Joined: Wed Nov 17, 2004 12:00 am
Location: Germany
Contact:

Post by bluecode »

I am reading "C++ Templates - The complete Guide". This book describes in chapter 6.2 the idea of "explicit instantiation". I just want to share this with you guys.
So the following is valid C++ and creates an instantiation of a template with a specific type:

Code: Select all

template void my_function_template<int>();
or for classes:

Code: Select all

template class my_class_template<int>;
That is just AWESOME! :D C++ keeps getting better each day (and that for years now) 8)

@JamesM: This is the standard compliant solution for your hack.
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

bluecode: If only! I have to force output of other symbols as well (see my code snippet), not just templated ones. It might make the hack a little neater but won't alleviate the need for it :(((((((((((((
Post Reply