2009-04-09 16 views
23

मैं एक फ़ंक्शन ट्रेसर को कार्यान्वित करना चाहता हूं, जो यह पता लगाएगा कि फ़ंक्शन निष्पादित करने में कितना समय लगता है। मैं उसी के लिए वर्ग निम्नलिखित हैं: -क्या सी ++ फ़ंक्शन के अंदर फ़ंक्शन नाम प्राप्त करने का कोई तरीका है?

class FuncTracer 
{ 
    public: 
     FuncTracer(LPCTSTR strFuncName_in) 
     { 
      m_strFuncName[0] = _T('\0'); 
      if(strFuncName_in || 
       _T('\0') != strFuncName_in[0]) 
      { 
       _tcscpy(m_strFuncName,strFuncName_in); 

       TCHAR strLog[MAX_PATH]; 
       _stprintf(strLog,_T("Entering Func:- <%s>"),m_strFuncName); 
       LOG(strLog) 

       m_dwEnterTime = GetTickCount(); 
      } 
     } 

     ~FuncTracer() 
     { 
      TCHAR strLog[MAX_PATH]; 
      _stprintf(strLog,_T("Leaving Func:- <%s>, Time inside the func <%d> ms"),m_strFuncName, GetTickCount()-m_dwEnterTime); 
      LOG(strLog) 
     } 

    private: 
     TCHAR m_strFuncName[MAX_PATH]; 
     DWORD m_dwEnterTime; 
}; 

void TestClass::TestFunction() 
{ 
    // I want to avoid writing the function name maually.. 
    // Is there any macro (__LINE__)or some other way to 
    // get the function name inside a function ?? 

    FuncTracer(_T("TestClass::TestFunction")); 
    /* 
    * Rest of the function code. 
    */ 
} 

मैं अगर वहाँ किसी भी तरह से एक समारोह के अंदर से समारोह के नाम पर प्राप्त करने के लिए है जानना चाहते हैं? असल में मैं चाहता हूं कि मेरी कक्षा के उपयोगकर्ता बस एक वस्तु बना सकें। वे फ़ंक्शन नाम पास नहीं कर सकते हैं।

उत्तर

21

कुलपति ++

__FUNCTION__ for undecorated names 

और

__FUNCDNAME__ for decorated names 

है और आप एक ऐसा मैक्रो ही एक वस्तु का आवंटन और निर्माता के अंदर नाम-yelding मैक्रो पारित करेंगे लिख सकते हैं। Smth तरह

#define ALLOC_LOGGER FuncTracer ____tracer(__FUNCTION__); 
+0

यह वीएस2003 में काम कर रहा है लेकिन वीसी 6 – Canopus

+0

में काम नहीं करता है क्या काम नहीं कर रहा है? मैक्रोज़ संकलक द्वारा मान्यता प्राप्त नहीं हैं या क्या? – sharptooth

+0

हां। वीसी 6 में संकलन पर यह __FUNCTION__ को अविकसित पहचानकर्ता के रूप में कहता है। क्या मुझे कुछ याद आ रहा है या क्या यह समर्थित नहीं है? – Canopus

46

C99 __func__ है, लेकिन सी के लिए ++ इस संकलक विशिष्ट हो जाएगा। प्लस तरफ, कुछ कंपाइलर-विशिष्ट संस्करण अतिरिक्त प्रकार की जानकारी प्रदान करते हैं, जो विशेष रूप से अच्छा होता है जब आप टेम्पलेटेटेड फ़ंक्शन/क्लास के अंदर ट्रेस कर रहे होते हैं।

  • MSVC: __FUNCTION__, __FUNCDNAME__, __FUNCSIG__
  • GCC: __func__, __FUNCTION__, __PRETTY_FUNCTION__

बूस्ट पुस्तकालय हेडर boost/current_function.hpp में सबसे सी ++ compilers के लिए मैक्रो BOOST_CURRENT_FUNCTION परिभाषित किया गया है। यदि संकलक इसका समर्थन करने के लिए बहुत पुराना है, तो परिणाम "(अज्ञात)" होगा।

3

मुझे लगता है मैं इस तरह के किसी भी बात का पता नहीं था लेकिन फिर मैं अन्य उत्तर देखा कहने के लिए जा रहा था ...

यह पता चला है कि एक निष्पादन प्रोफाइलर (जैसे gprof) वास्तव में क्या करता है अपनी दिलचस्पी आप 'के बारे में पूछ रहे हैं - यह प्रत्येक समारोह को निष्पादित करने में व्यतीत समय की मात्रा को ट्रैक करता है। एक प्रोफाइलर मूल रूप से निर्देश सूचक (आईपी), वर्तमान में निष्पादन निर्देश का पता, प्रत्येक 10ms या तो रिकॉर्ड करके काम करता है। कार्यक्रम चलाने के बाद, आप एक पोस्टप्रोसेसर का आह्वान करते हैं जो आईपी और कार्यक्रम की सूची की जांच करता है, और उन पते को फ़ंक्शन नामों में परिवर्तित करता है। तो मैं केवल फ़ंक्शन नाम के बजाय निर्देश सूचक का उपयोग करने का सुझाव दूंगा, क्योंकि दोनों कोड करना आसान है और क्योंकि स्ट्रिंग के मुकाबले एक संख्या के साथ काम करना अधिक कुशल है।

+1

ध्यान दें कि ऐसा करने के लिए, आपको निष्पादन योग्य/पुस्तकालयों के छवि लोड पते को भी सहेजना होगा, अन्यथा आप दर्ज किए गए पते को अर्थपूर्ण रूप से समझने में सक्षम नहीं होंगे। साथ ही, कस्टम प्रोफाइलर्स के लिए कंपाइलर समर्थन (उदा। एमएसवीसी में _penter/_pexit) आवधिक नमूनाकरण का विकल्प हो सकता है। – bk1e

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

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