2010-05-29 5 views
8

Belirli bir fonksiyonun derleme zamanında C-bağlantısıyla (yani extern "C" ile) bildirilmiş olup olmadığını kontrol etmenin bir yolu var mı?Bir fonksiyonun derleme zamanında C-bağlantısı olup olmadığını kontrol etme [çözülemez]

Bir eklenti sistemi geliştiriyorum. Her bir eklenti, fabrika işlevlerini eklenti yükleme koduna sağlayabilir. Bununla birlikte, bu, ad (ve GetProcAddress veya dlsym'un sonraki kullanımı) yoluyla yapılmalıdır. Bu, ad-manganlamanın önlenmesi için işlevlerin C-bağlantıyla bildirilmesini gerektirir. Eğer atıfta bulunulan işlev C++ - bağlantı ile bildirilmişse (bu isimde bir işlev bulunmadığında çalışma zamanında bulmak yerine) bir derleyici hatası atmak güzel olurdu.

Burada ne demek istediğimi basitleştirilmiş örnek:

extern "C" void my_func() 
{ 
} 

void my_other_func() 
{ 
} 

// Replace this struct with one that actually works 
template<typename T> 
struct is_c_linkage 
{ 
    static const bool value = true; 
}; 

template<typename T> 
void assertCLinkage(T *func) 
{ 
    static_assert(is_c_linkage<T>::value, "Supplied function does not have C-linkage"); 
} 

int main() 
{ 
    assertCLinkage(my_func); // Should compile 
    assertCLinkage(my_other_func); // Should NOT compile 
} 

ikinci fonksiyon için bir derleyici hatası atmak istiyorum is_c_linkage olası bir uygulaması var mı, ama ilk değil? Bunun mümkün olduğundan emin değilim (yine de bilmek istediğim bir derleyici uzantısı olarak mevcut olabilir). Teşekkürler.

+6

Bunun kesinlikle yapılamadığından şüpheliyim - özellikle standart bir şekilde değil. Yine de ilginç bir soru. –

+2

Bundan emin değilim. Ancak, eğer yapılabilirse bile, GCC'nin desteklemeyeceği oldukça olasıdır, çünkü bir extern "C" ve bir extern "C++" fonksiyon tipinin ayrımını bilmiyor. Böylece her iki türü de aynı şekilde ele alır. –

+0

Eğer uygulamaya özel bir bilgi verecekseniz, bir hata atmak yerine bu uygulama için çalışmasını sağlayabilirsiniz –

cevap

2

Jonathan Leffler ile aynı fikirdeyim ki bu muhtemelen standart bir şekilde mümkün değildir. Derleyicinin ve derleyicinin sürümüne bağlı olarak belki de bir şekilde mümkün olabilir, ancak olası yaklaşımları belirlemek ve derleyicinin davranışının kasıtsız olduğu ve daha sonraki sürümlerde "sabit" olabileceği gerçeğini kabul etmeniz gerekir.

void my_func() __attribute__((stdcall)); 
void my_func() { } 

void my_other_func() { } 

template <typename ret_, typename... args_> 
struct stdcall_fun_t 
{ 
    typedef ret_ (*type)(args_...) __attribute__((stdcall)); 
}; 

int main() 
{ 
    stdcall_fun_t<void>::type pFn(&my_func), 
     pFn2(&my_other_func); 
} 

g++ -std=c++0x çünkü bu kodu derlemek için başarısız:

sürüm 4.4.4 Debian Squeeze üzerinde g++ ile, örneğin, bu yaklaşımla değil stdcall fonksiyonlar için bir derleyici hata yükseltmek mümkün olabilir :

SO2936360.cpp:17: error: invalid conversion from ‘void ()()’ to ‘void ()()’

Hat 17 pFn2 ilanıdır. Bu bildiriden kurtulursam derleme başarılı olur.

Ne yazık ki, bu teknik cdecl ile çalışmaz.

0

Unix/Linux için, ortaya çıkan ikili 'nm' ile analiz etme ve sembol isimlerini bulma hakkında ne dersiniz? Sanırım istediğin gibi değil, ama yine de derleme zamanı.

İlgili konular