2012-08-11 24 views
6

ben Clang ile Mac OS X üzerinde çalışan almaya çalışıyorum bir C++ kütüphane var üzerinde başarısız olur. Kütüphane bir DLL ve bir Birim Testi yürütülebilir. Kütüphane -fvisibility=hidden yakalamak türetilen istisnalar tipleri Clang/MacOS X

  • ile derlenen

    • Tüm maruz sınıfları açıkça __attribute__(visibility("default")) kütüphane bazı istisna sınıfları vardır
    • olarak işaretlenir: Ben aşağıdaki ayarları kullanın, GCC ile, GCC ve MSVC ile iyi derler std::runtime_error'dan türetilmiştir. Tüm bu sınıflar varsayılan görünürlük için işaretlenmiştir. Daha spesifik istisnaların türetildiği bir LibraryException kök sınıfı vardır. istisnalar yanlış türde olduğundan
    • GCC, ben, kütüphane ve birim test çalıştırılabilir hem -stdlib=libc++ -std=c++11 Mac OS X'te

    , birim test çerçevesi şimdi başarısız ile inşa edilmiştir, clang, -std=c++0x kullanmak . Yani Böyle bir test başarısız:

    // bla.foo() throws CustomException, which is derived from LibraryException 
    TEST_THROWS (bla.foo(), CustomException) 
    
    // This works however 
    TEST_THROWS (bla.foo(), LibraryException) 
    

    benim özel istisna sınıfları typeinfo ve vtable nm -g library.dylib | c++filt -p -i kullanılarak dışa teyit ettik. Bütün istisnalar için durum böyle görünüyor ... burada ne halt oluyor? Hatalar üzerinde hata ayıklamaya çalıştım ve kütüphanede doğru türün nasıl atıldığını görüyorum ve aynı tür ünite test çalıştırıcısında yakalanamıyorum. Bu çalışma için Clang ile özel bir şey var mı? Test için SVN'nin en yeni googletest çerçevesini kullanıyorum. Bir boost::lexical_cast istisnası Kütüphanesi'nden atıldığında Ayrıca örneğin başarısız

    try { 
        funcThatThrowsCustomExceptionFromLibraryDylib(); 
    } catch (CustomException& e) { 
        // doesn't get here 
    } catch (LibraryException& e) { 
        // does get here 
        // after demangle, this prints CustomException 
        // Can cast down to CustomException and access the fields as well 
        std::cout << typeid (e).name() << "\n"; 
    } 
    

    :

    Küçük bir test programı

    aynı sorun sergiler.

  • cevap

    3

    İşte doğru çözümdür:

    görünürlük özelliğini uygulayarak

    , bu uygulanmalıdır hem de tüketilmesi halinde kütüphane de oluşturmasıyla başlar. Aksi halde, müşteri sınıfları görmez. boost :: lexical_cast için bu, nitelik mevcut, ancak görünüyor ki sen onlar Boost 1.50 itibariyle (istisna bir __attribute((visibility("default"))) ekleyerek kütüphanede sabit elde edene kadar

    #pragma GCC visibility push(default) 
    #include <boost/lexical_cast.hpp> 
    #pragma GCC visibility pop 
    

    kullanmak zorunda anlamına gelir Clang için destek henüz yok. Kütüphanede bir başlık içinde kullanıldığında, istemci kodunda düzgün bir şekilde yakalanabilir. Bu #pragma ayrıca Clang ile çalışır.

    bir atış() yıkıcı belirterek bazı şans yardım etti, ama kesinlikle doğru bir düzeltme değil aslında.

    +0

    Kesinlikle size yıkıcı kendiniz redeclare vermedi yoksa varsayılan birini inşa edilmiştir ... hatası gibi görünen? Gcc 4.3.2 ile 'exception''dan devralma sırasında' throw() 'belirteci olmadan bir yıkıcıyı bildirirsem uyarı alırım. –

    +0

    KütüphaneException olarak yeniden kaydettim ~ LibraryException() throw(); aksi halde GCC 4.6, varsayılanın yanlış atma belirtimine veya benzer bir şeye sahip olduğundan şikâyetçi olmuştur. – Anteru