On Mon, May 23, 2011 at 10:51 AM, Sanatan Rai <span dir="ltr"><<a href="mailto:sanatan@gmail.com">sanatan@gmail.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">On 23 May 2011 15:11, Michael Wild <<a href="mailto:themiwi@gmail.com">themiwi@gmail.com</a>> wrote:<br>
>>> Yes, but you are registering the concrete factories implicitly instead<br>
>>> of explicitly, which is causing you the trouble you experience.<br>
>>><br>
>>> Better have your user provide a function registering his/her classes<br>
>>> explicitly.<br>
>><br>
>> I guess this is getting to be off topic, but indeed the<br>
>> anonymous namespace trick is supposed to do exactly that.<br>
</div><snipped><br>
<div class="im">>> libraries that this problem occurs. I haven't seen a solution to this<br>
>> problem either in books or via google.<br>
>><br>
>> --Sanatan<br>
><br>
> The problem is, that when you link a static library to another binary<br>
> (be it shared library or executable) only the *required* symbols are<br>
> used, all others get discarded. Since nothing in your code actually<br>
> references those global instances in the anonymous namespace (the linker<br>
> doesn't care about that, BTW), they are ignored.<br>
><br>
> Four solutions:<br>
><br>
> 1. Only do monolithic builds.<br>
> 2. Use shared libraries/DLLs<br>
> 3. Use --whole-archive or similar and hack your way through MSVC (I did<br>
> it once. It was ugly. Very ugly. See<br>
> <a href="https://github.com/themiwi/cppcheck/tree/227378f763d50b005b7dd2167e2cef791054a30c" target="_blank">https://github.com/themiwi/cppcheck/tree/227378f763d50b005b7dd2167e2cef791054a30c</a>.<br>
> Especially lib/CMakeLists.txt and lib/generateStaticLinkFlags.cmake. I<br>
> replaced it with an explicit registration scheme now...)<br>
> 4. Use an explicit registration scheme.<br>
><br>
> For sanity's sake, go with 4.<br>
<br>
</div> Ok: you've lost me here. Are you saying a trick like:<br>
<br>
namespace {<br>
helper1 *createHelper1() { return (new Helper1());}<br>
const bool isRegistered =<br>
factory::instance().registerHelper("helper1", createHelper1);<br>
}<br>
isn't explicit?<br></blockquote><div><br></div><div>That's correct. It's not explicit. Because if nothing references the bool variable "isRegistered" then the linker is free to (possibly) throw away it's initialization because it's not referenced. This code may work with some compilers; but it is not guaranteed to work.</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
I could do the following: create a global object in the cpp, that<br>
belongs to a type that would<br>
do the registration. Would you regard this also as implicit?<br>
<br>
The problem with either of these approaches is the same: if the code<br>
lives in a separate library<br>
that is loaded only when needed, then these registrations don't take<br>
place. So the framework doesn't<br>
know that the objects can be available.<br>
<br>
Apologies for seeming obtuse but I don't follow what you mean by<br>
`explicit registration' here.<br></blockquote><div><br></div><div>Explicit registration is having a method as mentioned earlier, something like "RegisterKnownFactories" and then asking clients to make sure they call that method first before calling anything that requires a factory to create something.</div>
<div><br></div><div>HTH,</div><div>David</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<font color="#888888"><br>
--Sanatan<br>
</font><div><div></div><div class="h5">_______________________________________________<br>
Powered by <a href="http://www.kitware.com" target="_blank">www.kitware.com</a><br>
<br>
Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
<br>
Please keep messages on-topic and check the CMake FAQ at: <a href="http://www.cmake.org/Wiki/CMake_FAQ" target="_blank">http://www.cmake.org/Wiki/CMake_FAQ</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a href="http://www.cmake.org/mailman/listinfo/cmake" target="_blank">http://www.cmake.org/mailman/listinfo/cmake</a><br>
</div></div></blockquote></div><br>