2016-03-11 10 views
5

मेरे पास हेडर है, उदाहरण के लिए #include <GL/gl.h>। इसमें ओपनजीएल एपीआई फ़ंक्शंस का सबसेट शामिल है।संकलन समय पर वैश्विक दायरे में फ़ंक्शन घोषित किया गया है या नहीं,

static_assert(has_glDrawArraysIndirect::value, "There is no glDrawArraysIndirect"); 

या और भी बेहतर:: मैं कुछ इस तरह की जरूरत है

PFNGLDRAWARRAYSINSTANCEDPROC ptr_glDrawArraysIndirect = ptr_to_glDrawArraysIndirect::ptr; 

कहाँ ptr_to_glDrawArraysIndirect::ptr glDrawArraysIndirect सूचक को अगर यह एक ठूंठ समारोह stub_glDrawArraysIndirect अन्यथा करने के लिए परिभाषित या है unrolls।

मेरा लक्ष्य ऑपरेटिंग सिस्टम बहुत विशिष्ट है। कोई भी लिंकर आधारित समाधान (जैसे GetProcAddress या dlsym) मेरे लिए काम नहीं करता है, क्योंकि कोई गतिशील लिंकर नहीं है। इससे अधिक, मेरा चालक glXGetProcAdrress और न ही wglGetProcAddress प्रदान करता है, मूल रूप से फ़ंक्शन नाम से रन टाइम पर पॉइंटर पूछने का कोई तरीका नहीं है (असल में, मैं इस तरह के तंत्र को कार्यान्वित करना चाहता हूं)।

कोई विचार?

+1

यदि कोई गतिशील लिंकिंग नहीं है, तो यह स्थिर रूप से लिंक होना चाहिए। तो या तो संकलन समय पर कार्य मौजूद है या यह नहीं है। और चूंकि यह एक शीर्षलेख की सामग्री द्वारा निर्धारित किया जाएगा, आप बस उस पर देख सकते हैं। –

+0

@ निकोल बोलस: यही वह है जो मैं लंबे समय से कर रहा था। चूंकि चालक भारी विकास में है, इसलिए मैं अपना कोड अपडेट करने से थक गया हूं। मैं सामान्य रूप से इसे हल करना चाहता हूं। – ivaigult

उत्तर

5

यहां एक उत्तर है जो इसे संकलित समय पर पहचान सकता है और एक बूलियन मान उत्पन्न कर सकता है। यह नामस्थान में एक ही नाम का टेम्पलेट फ़ंक्शन बनाकर और फिर उस नामस्थान का उपयोग is_defined() फ़ंक्शन के अंदर करता है। यदि असली glDrawArraysIndirect() मौजूद है तो यह टेम्पलेट संस्करण पर वरीयता लेगा। यदि आप glDrawArraysIndirect() की पहली घोषणा को टिप्पणी करते हैं तो नीचे स्थिर स्थिरता ट्रिगर होगी।

Test on GodBolt

#include <type_traits> 

enum GLenum {}; 

void glDrawArraysIndirect(GLenum, const void*); 

namespace detail { 
    struct dummy; 

    template<typename T> 
    dummy& glDrawArraysIndirect(T, const void*); 
} 

constexpr bool is_defined() 
{ 
    using namespace detail; 
    using ftype = decltype(glDrawArraysIndirect(GLenum(), nullptr)); 
    return std::is_same<ftype, void>(); 
} 

static_assert(is_defined(), "not defined"); 
एक छोटे से ट्वीक साथ

आप कैसे जाँच करने के लिए अपने कस्टम समारोह टेम्पलेट एक समान चाल

ideone.com

#include <type_traits> 
#include <iostream> 

//#define USE_REAL 

enum GLenum {TEST}; 

typedef void (*func_type)(GLenum, const void*); 

#ifdef USE_REAL 
void glDrawArraysIndirect(GLenum, const void*); 
#endif 

namespace detail { 
    struct dummy {}; 

    template<typename T = dummy> 
    void glDrawArraysIndirect(GLenum, const void*, T = T()) 
    { 
     std::cout << "In placeholder function" << std::endl; 
    } 

} 

void wrapDraw(GLenum x, const void* y) 
{ 
    using namespace detail; 
    glDrawArraysIndirect(x, y); 
} 

#ifdef USE_REAL 
void glDrawArraysIndirect(GLenum, const void*) 
{ 
    std::cout << "In real function" << std::endl; 
} 
#endif 

int main() 
{ 
    wrapDraw(TEST, nullptr); 
} 
+1

यह वही है जो मैं ढूंढ रहा हूं। आपने मेरा दिन बनाया है, धन्यवाद! – ivaigult

+0

वाह, यह जादू बिल्कुल वही है जो मुझे चाहिए। –

+0

वास्तव में, दूसरे उदाहरण के लिए आपको नामस्थान या डमी या डिफ़ॉल्ट टेम्पलेट तर्क की आवश्यकता नहीं है। बस 'टी' जेनेरिक प्रकार को 'जीलेनम' की जगह ले जाएं और इसे ओवरलोड रिज़ॉल्यूशन में वास्तविक के पीछे चुना जाएगा। –

2

कहीं भी sizeof(::function) अभिव्यक्ति शामिल करें। (यदि फ़ंक्शन मौजूद है तो फ़ंक्शन में पॉइंटर के आकार के लिए पूछना एक पूरी तरह से मान्य बात है)।

यह रनटाइम पर सौम्य होगा, और :: वैश्विक दायरे में घोषित function के उपयोग को मजबूर करता है।

बेशक, यदि function वैश्विक दायरे में मौजूद नहीं है, तो संकलन विफल हो जाएगा।

अन्य त्रुटियों के साथ साथ, संकलक एक विशिष्ट त्रुटि जारी करेगा अगर आप

static_assert(sizeof(::function), "There is no global function");

+0

'static_assert (sizeof (:: function)," कोई वैश्विक कार्य नहीं है ");' –

+0

@RSahu: अगर आप इसके साथ जवाब खत्म करते हैं तो आपको बुरा लगेगा? – Bathsheba

+0

बेशक नहीं। आगे बढ़ें। –

1

मेरे लक्ष्य ऑपरेटिंग सिस्टम बहुत विशिष्ट है की तर्ज पर कुछ लिखने के लिए थे। कोई भी लिंकर आधारित समाधान (जैसे GetProcAddress या dlsym) मेरे लिए काम नहीं करता है, क्योंकि कोई गतिशील लिंकर नहीं है।

क्या यह एक एम्बेडेड सिस्टम है या मानक पीसी हार्डवेयर पर बस एक अजीब तरह से छीन लिया गया ओएस चल रहा है?

से अधिक, मेरी चालक glXGetProcAdrress है और न ही wglGetProcAddress प्रदान नहीं करता है, मूल रूप से वहाँ समारोह नाम से रन टाइम पर सूचक क्वेरी करने के लिए

abiliy समारोह संकेत क्वेरी करने के लिए क्रम नहीं है पर कोई रास्ता नहीं है एक गतिशील लिंकर की उपस्थिति पर निर्भर करता है। वे दोनों पूरी तरह से ऑर्थोगोनल हैं और यहां तक ​​कि पूरी तरह से स्थिर रूप से जुड़े एम्बेडेड ओपनजीएल कार्यान्वयन GetProcAddress इंटरफेस को ठीक से पेश कर सकते हैं। किसी भी तरह संकलन या लिंक समय पर समस्या को हल करने की कोशिश करने के बजाय, मैं आपके OpenGL ड्राइवर के लिए GetProcAddress लागू करके समस्या का समाधान करना चाहता हूं; आप यह भी कर सकते हैं भले ही ड्राइवर बाइनरी रूप में केवल एक स्थिर पुस्तकालय के रूप में उपलब्ध हो। चरण एक:

प्रत्येक ओपनजीएल फ़ंक्शन के लिए फ़ंक्शन पॉइंटर स्टब्स बनाएं, जो सांख्यिकीय रूप से प्रारंभिक और प्रारंभिक कमजोर लिंक के लिए प्रारंभिक है। इसे एक स्थिर लाइब्रेरी में लिंक करें जिसे आप gl_null_stubs या इसी तरह कॉल कर सकते हैं।

GetProcAddress फ़ंक्शन बनाएं जो प्रत्येक ओपनजीएल फ़ंक्शन के लिए फ़ंक्शन की संकलन इकाई के दायरे में फ़ंक्शन प्रतीक को पॉइंटर देता है।

अब अपने अजीब OpenGL ड्राइवर को स्टब्स लाइब्रेरी और GetProcAddress कार्यान्वयन के साथ लिंक करें। प्रत्येक समारोह के लिए, स्टब का कमजोर संबंध स्थिर लाइब्रेरी प्रतीक को प्राथमिकता लेगा। सभी ओपनजीएल प्रतीकों के लिए आपके ड्राइवर में नहीं, स्टब्स खत्म हो जाएंगे।

वहां: अब आपके पास ओपनजीएल ड्राइवर लाइब्रेरी है जो एक GetProcAddress कार्यान्वयन है। वह मुश्किल नहीं था, है ना?

1

बनाने के लिए और उपयोग कर सकते हैं, तो समारोह घोषित किया जाता है संकलन समय पर वैश्विक दायरे में? मेरे लक्ष्य ऑपरेटिंग सिस्टम बहुत विशिष्ट है ...

सम्भावित समाधान, हो सकता है अगर आप gcc अनुकूलित करने के लिए (-probably हाल ही में एक GCC उपयोग कर रहे हैं अपने अजीब लक्ष्य ओएस और ABI- के लिए एक पार संकलक के रूप में या g++ आदि ...) अपने खुद के MELT एक्सटेंशन के साथ कंपाइलर।

एमईएलटी एक डोमेन विशिष्ट भाषा है, जिसे जीसीसी कंपाइलर को अनुकूलित करने के लिए एक मुफ्त सॉफ्टवेयर जीसीसी प्लगइन (ज्यादातर लिनक्स पर) के रूप में लागू किया गया है।

संबंधित मुद्दे