2017-03-14 22 views
17

, ben class Foo var ve class __attribute__((visibiility("default"))) Foo gibi bir bildiri aracılığıyla o default görünürlük verdiyseniz, elimden sonra __attribute__((visibility("hidden")) ile bunları açıkça açıklamalar ekleyerek default görünürlüğünü sahip olmaktan sınıfın selektif muaf belli üyeler. Bu class Foo tanımlayan kütüphanesi inşa ederken yayılan, bunlar dışa böylece, ABI bir parçasını oluşturabilir veya aynı zamanda bir parçasını oluşturmaması gerekmektedir class Foo içinde private üye veya türleri için gereken içi yöntemleri için yararlı olabilir onun ABI. Bununla birlikte, Windows'ta, bunu başarmanın hiçbir yolu olmadığı görülmektedir. Unutulmamış bir class Foo otomatik olarak bir DLL için özel olarak, bir kez class __declspec(dllexport) Foo olarak süslenmiş iken, tüm sınıf şimdi dllexport ve belirli bir üyenin __dllexport durumunu seçici olarak geçersiz kılacak ilişkili bir ek açıklama görünmüyor. "Dışa aktarma değil" üyelerini __declspec(dllimport) olarak etiketlemek açıkça yanlıştır.Üyelik esasına göre sınıflandırılmış bir __declspec (dllexport) notu nasıl geçersiz kılabilirim? ELF hedefler üzerinde

Sınıflandırılmış __dllexport sınıfının belirli sınıf üyelerine ve/veya türlerine uygulanmasını engellemenin başka bir yolu var mı?

ben söylemek istiyorum, ne Bunu daha somut hale getirmek için, ve diyebiliriz, ELF ek açıklamaları kullanırken geçerli:

class __attribute__((visibility("default"))) Foo { 
public: 
    Foo(); // OK, default visibility 

    // Don't let inlines join the ABI 
    __attribute__((visibility("hidden")) inline void something() { ... } 

private: 
    // Don't let private members join the ABI 
    __attribute__((visibility("hidden")) void _internal(); 

    // Our pImpl type is also not part of the ABI. 
    struct __attribute__((visibility("hidden")) pimpl; 
}; 

Ama MSVC kullanarak aynı şeyi oluşamaz nitelikleri:

bir gerçek dünya uygulamasında
class __declspec(dllexport) Foo { 
public: 
    Foo(); // OK, dllexport'ed 

    // Don't let inlines join the ABI, but how to say it? 
    __declspec(???) inline void something() { ... } 

private: 
    // Don't let private members join the ABI, but how? 
    __declspec(???) void _internal(); 

    // Our pImpl type is also not part of the ABI, but how? 
    struct __declspec(???) pimpl; 
}; 

, ben bu arasındaki varyasyon bir makro arkasında gizlenmiş gibi beklersiniz.

__attribute__((visibility("hidden"))) anlambilimine sahip olan ve __declspec(dllexport) sınıf kapsamı uygulamasını geçersiz kılabilen bazı __declspec var mı?

+0

Bilginize _ "satır içi yöntemleri olduğunu ABI'nin bir parçasını oluşturmamalı, "inline, satır içi (inline özel force-inline uzantıları kullanmıyorsanız) satır içi anlamına gelmez. Yani onlar ABI'nin bir parçası, satır içi hatta en modern derleyiciler için bir ipucu bile değil. –

+0

da sınıfının genel bir yöntem (aynı sınıfın) özel bir yöntemini çağırır ve genel yöntem istemci uygulaması inlined ise; Daha sonra, özel yöntemin linker görünür olması ve ABI'nın bir parçasını oluşturması gerekir. –

+0

@Richard Critten İkinci yorumunuza tamamen katılıyorum, ancak bu izlenebilir - sadece özel üyeleri aramak zorunda olan bu kamu yöntemlerini kullanmayın ve uygulamada bulunmamıştır. İlk yorumunuza, inline'ın derleyici için "bir ipucu bile değil" olduğunu kabul ediyorum, ancak bağlantı üzerinde etkileri var. -Fvisibility-inline-hidden 'in ELF platformları üzerindeki etkilerini düşünün. ABI'nin bir parçasını oluşturmayan satır içi argümanı, satır içi yöntemin ABI yöntemlerine basitçe aktardığı sürece, istemcinin ve kitaplığın anlamıyla farklılaşıp farklılaşmayacağı konusundaki fikri üzerinde durmaktadır. – acm

cevap

0

Hiç böyle bir şey yapmadım, ancak the MSDN documentation'u takiben mümkün olmalıdır.

Sınıf düzeyinde hiçbir __declspec belirtmemelisiniz ve yalnızca üyeler için istediğiniz __declspec(dllexport) belirtmelisiniz.

Bu yardımın umarım.

1

MSDN documentation bu yapılabilir nasıl bir fikir verir. İşte bir örnek.

DLL_declspec.h:

#include "DLL_declspec.h" 

class DLL_DECLSPEC TestExport 
{ 
    public: 

     TestExport(); 

     ~TestExport(); 

     std::string getName(); 

     int getID(); 
}; 

sınıfın sadece bir Handpicked üyeleri aktarmak için:

#elif defined(BUILD_DLL) 
    #define DLL_DECLSPEC __declspec(dllexport) 
#else 
    #define DLL_DECLSPEC __declspec(dllimport) 
#endif 

bütün sınıfı aktarmak için

#include "DLL_declspec.h" 

class TestExport 
{ 
    public: 

     DLL_DECLSPEC TestExport(); 

     DLL_DECLSPEC ~TestExport(); 

     DLL_DECLSPEC std::string getName(); 

     int getID(); 
}; 
İlgili konular