<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Aug 6, 2015 at 1:21 PM, Edward Diener <span dir="ltr"><<a href="mailto:eldlistmailingz@tropicsoft.com" target="_blank">eldlistmailingz@tropicsoft.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 8/6/2015 12:44 PM, Reid Kleckner wrote:<br>
</span><span class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hm, GCC never tries to import RTTI, so maybe it makes sense that we<br>
never export it. Anyway, there's a bug here. Maybe David knows what's up.<br>
</blockquote>
<br></span>
I tried this simple example:<br>
<br>
// ex_aclass.hpp<br>
<br>
#ifndef EX_ACLASS_HPP<br>
#define EX_ACLASS_HPP<span class=""><br>
#if defined(BLD_EX_EXAMPLE)<br>
        #define EX_DECL __attribute__((__dllexport__))<br>
#else<br>
        #define EX_DECL __attribute__((__dllimport__))<br>
#endif<br></span>
class EX_DECL ex_aclass<br>
{<br>
public:<br>
    int a_function(long);<br>
};<br>
#endif // EX_ACLASS_HPP<br>
<br>
// ex_aclass.cpp<br>
<br>
#define BLD_EX_EXAMPLE<br>
#include "ex_aclass.hpp"<br>
int ex_aclass::a_function(long amt)<br>
        {<br>
        return(amt > 1000000 ? 10 : 20);<br>
        }<br>
<br>
// Compile ex_aclass<br>
<br>
clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -O0 -g -fno-inline -Wall -g -march=i686 -m32 -o "ex_aclass.obj" "ex_aclass.cpp"<br>
<br>
// Link to ex_ac dll<br>
<br>
clang++.exe -o "ex_ac.dll" -Wl,-soname -Wl,ex_ac.dll -shared -Wl,--start-group "ex_aclass.obj" -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32<br>
<br>
// ex_use_aclass.cpp<br>
<br>
#include "ex_aclass.hpp"<span class=""><br>
int main(int argc,char * argv[])<br>
        {<br></span>
        ex_aclass aclass;<br>
        int ret(aclass.a_function(10000));<br>
        return ret;<br>
        }<br>
<br>
// Compile ex_use_aclass<br>
<br>
clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -O0 -g -fno-inline -Wall -g -march=i686 -m32 -o "ex_use_aclass.obj" "ex_use_aclass.cpp"<br>
<br>
// Link ex_use_ac executable<br>
<br>
clang++.exe -Wl,-R -Wl,"." -Wl,-rpath-link -Wl,"." -o "ex_use_ac.exe" -Wl,--start-group "ex_use_aclass.obj" "ex_ac.dll" -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32<br>
<br>
All of this worked with no problems.<br>
<br>
So the basic ability to access functionality in a class in a DLL from outside that DLL works fine using clang on Windows. It is something specific in my original example below that is causing linking problems, whether I export entire classes or whether I export individual member functions. Just thought I would let you know. Needless to say I need to solve my original problem because that code mimics the design of a very small portion of the Boost serialization library and is the cause why the Boost serialization library will not build with clang on Windows targeting gcc.<br></blockquote><div><br></div><div>Should be fixed in r244266.<br></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>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
<br>
On Thu, Aug 6, 2015 at 9:36 AM, Reid Kleckner<br></span>
<<a href="mailto:rnk-hpIqsD4AKlfQT0dZR%2BAlfA@public.gmane.org" target="_blank">rnk-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org</a><div><div class="h5"><br>
<mailto:<a href="mailto:rnk-hpIqsD4AKlfQT0dZR%2BAlfA@public.gmane.org" target="_blank">rnk-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org</a>>> wrote:<br>
<br>
    I reproduced your example, and it looks like we are forgetting to<br>
    export RTTI with dllexport in Itanium. We only export the vtable.<br>
    This is what each compiler exports for ex_xml_exception.obj:<br>
<br>
    $ dumpbin -directives ex_xml_exception.clang.obj | grep -export:_ZT<br>
    | c++filt --no-strip-underscore<br>
        -export:virtual thunk to ex_xml_exception::~ex_xml_exception()<br>
        -export:virtual thunk to ex_xml_exception::~ex_xml_exception()<br>
        -export:vtable for ex_xml_exception,data<br>
<br>
    $ dumpbin -directives ex_xml_exception.gcc.obj | grep -export:_ZT |<br>
    c++filt --no-strip-underscore<br>
        -export:typeinfo for ex_exception,data<br>
        -export:typeinfo for ex_xml_exception,data<br>
        -export:construction vtable for<br>
    ex_exception-in-ex_xml_exception,data<br>
        -export:VTT for ex_xml_exception,data<br>
        -export:vtable for ex_xml_exception,data<br>
        -export:virtual thunk to ex_xml_exception::~ex_xml_exception()<br>
        -export:virtual thunk to ex_xml_exception::~ex_xml_exception()<br>
<br>
    In your previous example where the whole class wasn't exported, I<br>
    think we might be doing the wrong thing when the key function is<br>
    dllimport / dllexport. We think that it will provide exported<br>
    symbols for vtables and RTTI but it doesn't. This is something we<br>
    didn't run into because the MSVC ABI doesn't have key functions.<br>
<br>
    On Thu, Aug 6, 2015 at 6:16 AM, Edward Diener<br>
    <<a href="mailto:eldlistmailingz@tropicsoft.com" target="_blank">eldlistmailingz@tropicsoft.com</a><br></div></div><div><div class="h5">
    <mailto:<a href="mailto:eldlistmailingz-5p0dqD" target="_blank">eldlistmailingz-5p0dqD</a>/<a href="mailto:c5LGWd6l5hS35sQ@public.gmane.org" target="_blank">c5LGWd6l5hS35sQ@public.gmane.org</a>>> wrote:<br>
<br>
        Using clang on Windows targeting mingw(-64)/gcc since it does<br>
        not appear possible to export individual member functions of a<br>
        class, as well as export the RTTI of the class, without<br>
        exporting the entire class, I have changed my example in my post<br>
        "Linker error and obfuscated name" to export the entire class<br>
        itself. But I am still seeing a linker error, Here is the<br>
        changed code and command lines:<br>
<br>
        // ex_decl.hpp<br>
<br>
        #ifndef EX_DECL_HPP<br>
        #define EX_DECL_HPP<br>
        #if defined(BLD_EX_EXAMPLE)<br>
             #define EX_DECL __attribute__((__dllexport__))<br>
        #else<br>
             #define EX_DECL __attribute__((__dllimport__))<br>
        #endif<br>
        #endif // EX_DECL_HPP<br>
<br>
        // ex_exception.hpp<br>
<br>
        #ifndef EX_EXCEPTION_HPP<br>
        #define EX_EXCEPTION_HPP<br>
        #include <exception><br>
        #include "ex_decl.hpp"<br>
        class EX_DECL ex_exception :<br>
             public virtual std::exception<br>
        {<br>
        private:<br>
             char m_buffer[128];<br>
        protected:<br>
             unsigned int append(unsigned int l, const char * a);<br>
             ex_exception() ;<br>
        public:<br>
             typedef enum {<br>
               no_exception,<br>
               other_exception<br>
             } ex_exception_code;<br>
             ex_exception_code code;<br>
             ex_exception(ex_exception_code c,const char * e1 = 0,const<br>
        char * e2 = 0) ;<br>
             ex_exception(ex_exception const &) ;<br>
             virtual ~ex_exception() throw() ;<br>
             virtual const char * what() const throw() ;<br>
        };<br>
        #endif // EX_EXCEPTION_HPP<br>
<br>
        // ex_exception.cpp<br>
<br>
        #include <exception><br>
        #include <cstring><br>
        #define BLD_EX_EXAMPLE<br>
        #include "ex_exception.hpp"<br>
        unsigned int ex_exception::append(unsigned int l, const char * a){<br>
             while(l < (sizeof(m_buffer) - 1)){<br>
                 char c = *a++;<br>
                 if('\0' == c)<br>
                     break;<br>
                 m_buffer[l++] = c;<br>
             }<br>
             m_buffer[l] = '\0';<br>
             return l;<br>
        }<br>
        ex_exception::ex_exception(ex_exception_code c,const char *<br>
        e1,const char * e2) : code(c)<br>
        {<br>
           unsigned int length = 0;<br>
             switch(code){<br>
             case no_exception:<br>
                 length = append(length, "uninitialized exception");<br>
                 break;<br>
             case other_exception:<br>
                 length = append(length, "unknown derived exception");<br>
                 break;<br>
             default:<br>
                 length = append(length, "programming error");<br>
                 break;<br>
             }<br>
        }<br>
        ex_exception::ex_exception(ex_exception const & oth) :<br>
        std::exception(oth),code(oth.code)<br>
        {<br>
             std::memcpy(m_buffer,oth.m_buffer,sizeof m_buffer);<br>
        }<br>
        ex_exception::~ex_exception() throw() {}<br>
        const char * ex_exception::what() const throw() { return<br>
        m_buffer; }<br>
        ex_exception::ex_exception() : code(no_exception) {}<br>
<br>
        // Compile ex_exception.cpp<br>
<br>
        clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS<br>
        -Wno-unused-local-typedef -Wno-dll-attribute-on-redeclaration<br>
        -O0 -g -fno-inline -Wall -g -march=i686 -m32 -o<br>
        "ex_exception.obj" "ex_exception.cpp"<br>
<br>
        // ex_xml_exception.hpp<br>
<br>
        #ifndef EX_XML_EXCEPTION_HPP<br>
        #define EX_XML_EXCEPTION_HPP<br>
        #include <exception><br>
        #include "ex_decl.hpp"<br>
        #include "ex_exception.hpp"<br>
        class EX_DECL ex_xml_exception :<br>
             public virtual ex_exception<br>
        {<br>
        public:<br>
             typedef enum {<br>
                 xml_archive_parsing_error,<br>
                 xml_archive_tag_mismatch,<br>
                 xml_archive_tag_name_error<br>
             } ex_exception_code;<br>
             ex_xml_exception(ex_exception_code c,const char * e1 =<br>
        0,const char * e2 = 0);<br>
             ex_xml_exception(ex_xml_exception const &) ;<br>
             virtual ~ex_xml_exception() throw() ;<br>
        };<br>
        #endif // EX_XML_EXCEPTION_HPP<br>
<br>
        // ex_xml_exception.cpp<br>
<br>
        #include <exception><br>
        #define BLD_EX_EXAMPLE<br>
        #include "ex_xml_exception.hpp"<br>
        ex_xml_exception::ex_xml_exception(ex_exception_code c,const<br>
        char * e1,const char * e2) :<br>
                 ex_exception(other_exception, e1, e2)<br>
             {<br>
                 switch(c){<br>
                 case xml_archive_parsing_error:<br>
                     ex_exception::append(0, "unrecognized XML syntax");<br>
                     break;<br>
                 case xml_archive_tag_mismatch:<br>
                     ex_exception::append(0, "XML start/end tag mismatch");<br>
                     if(0 != e1){<br>
                         ex_exception::append(0, " - ");<br>
                         ex_exception::append(0, e1);<br>
                     }<br>
                     break;<br>
                 case xml_archive_tag_name_error:<br>
                     ex_exception::append(0, "Invalid XML tag name");<br>
                     break;<br>
                 default:<br>
                     ex_exception::append(0, "programming error");<br>
                     break;<br>
                 }<br>
             }<br>
        ex_xml_exception::ex_xml_exception(ex_xml_exception const & oth)<br>
        : std::exception(oth),ex_exception(oth){}<br>
        ex_xml_exception::~ex_xml_exception() throw() {}<br>
<br>
        // Compile ex_xml_exception.cpp<br>
<br>
        clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS<br>
        -Wno-unused-local-typedef -Wno-dll-attribute-on-redeclaration<br>
        -O0 -g -fno-inline -Wall -g -march=i686 -m32 -o<br>
        "ex_xml_exception.obj" "ex_xml_exception.cpp"<br>
<br>
        // Link exmp-clang37-d-1_59.dll<br>
<br>
        clang++.exe -o "exmp-clang37-d-1_59.dll" -Wl,-soname<br>
        -Wl,exmp-clang37-d-1_59.dll -shared -Wl,--start-group<br>
        "ex_exception.obj" "ex_xml_exception.obj"  -Wl,-Bstatic<br>
        -Wl,-Bdynamic  -Wl,--end-group -g -march=i686 -m32<br>
<br>
        // throw_exception_ex.cpp<br>
<br>
        #include "ex_xml_exception.hpp"<br>
        template<class E> void throw_exception(E const & e) { throw e; }<br>
        int main(int argc,char * argv[])<br>
        {<br>
             if (argc > 1)<br>
                   {<br>
<br>
        throw_exception(ex_xml_exception(ex_xml_exception::xml_archive_parsing_error));<br>
<br>
                   }<br>
             return 0;<br>
        }<br>
<br>
        // Compile throw_exception_ex.cpp<br>
<br>
        clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS<br>
        -Wno-unused-local-typedef -Wno-dll-attribute-on-redeclaration<br>
        -O0 -g -fno-inline -Wall -g -march=i686 -m32 -o<br>
        "throw_exception_ex.obj" "throw_exception_ex.cpp"<br>
<br>
        // Link thr_exmp.exe<br>
<br>
        clang++.exe -Wl,-R -Wl,"." -Wl,-rpath-link -Wl,"." -o<br>
        "thr_exmp.exe" -Wl,--start-group "throw_exception_ex.obj"<br>
        "exmp-clang37-d-1_59.dll" -Wl,-Bstatic -Wl,-Bdynamic<br>
        -Wl,--end-group -g -march=i686 -m32<br>
<br>
        // Error message from this link<br>
<br>
        throw_exception_ex.obj: In function<br>
        `Z15throw_exceptionI16ex_xml_exceptionEvRKT_':<br>
        throw_exception_ex.cpp:2: undefined reference to<br>
        `_imp___ZTI16ex_xml_exception'<br>
        clang++.exe: error: linker command failed with exit code 1 (use<br>
        -v to see invocation)<br>
<br>
        So even when I export/import the entire class rather than<br>
        individual member functions, I can not link my final module<br>
        successfully as it is still looking for something in the shared<br>
        library that it says is not there.<br>
<br>
        This same code succeeds without problem with mingw(-64)/gcc on<br>
        Windows.<br>
</div></div></blockquote><div class="HOEnZb"><div class="h5">
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</div></div></blockquote></div><br></div></div>