Page 1 of 1
C++ Templates & shared-libraries
Posted: Thu Sep 27, 2007 1:12 am
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?
Posted: Thu Sep 27, 2007 5:11 am
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();
}
Posted: Thu Sep 27, 2007 5:55 am
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
Posted: Thu Sep 27, 2007 11:23 am
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
Re: C++ Templates & shared-libraries
Posted: Thu Sep 27, 2007 10:07 pm
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.
Posted: Sun Sep 30, 2007 4:39 am
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.
Thank you Solar and JamesM!
Posted: Tue Oct 09, 2007 1:30 pm
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!
C++ keeps getting better each day (and that for years now)
@JamesM: This is the standard compliant solution for your hack.
Posted: Wed Oct 10, 2007 3:42 am
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
((((((((((((