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?
C++ Templates & shared-libraries
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.
Then in my kernel init function adding a:
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:
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);
}
Code: Select all
if (false) registerSharedTemplates();
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();
}
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
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
Re: C++ Templates & shared-libraries
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.bluecode wrote:I read somewhere that it breaks the existing toolchains, but why?
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.
Your right... somehow I was thinking that you have to provide the definition for all your template foobar.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.
Thank you Solar and JamesM!
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:
or for classes:
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.
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>();
Code: Select all
template class my_class_template<int>;
@JamesM: This is the standard compliant solution for your hack.