2009-04-09 26 views
23

Tôi muốn triển khai trình theo dõi chức năng, sẽ theo dõi lượng thời gian mà một hàm đang thực hiện. Tôi có lớp học sau cho cùng một: -Có cách nào để lấy tên hàm bên trong hàm C++ không?

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. 
    */ 
} 

Tôi muốn biết có cách nào để lấy tên hàm từ bên trong một hàm không? Về cơ bản tôi muốn người dùng của lớp của tôi chỉ đơn giản là tạo một đối tượng giống nhau. Họ có thể không vượt qua tên hàm.

Trả lời

21

VC++ có

__FUNCTION__ for undecorated names 

__FUNCDNAME__ for decorated names 

Và bạn có thể viết một macro mà bản thân sẽ phân bổ một đối tượng và vượt qua các tên yelding macro bên trong constructor. Smth như

#define ALLOC_LOGGER FuncTracer ____tracer(__FUNCTION__); 
+0

Hoạt động của nó trong VS2003 nhưng không hoạt động ở VC6 – Canopus

+0

Điều gì không hoạt động? Các macro không được trình biên dịch nhận ra hay gì? – sharptooth

+0

Có. Khi biên dịch trong VC6, nó cho biết __FUNCTION__ là mã định danh không khai báo. Tôi có thiếu cái gì đó hay nó không được hỗ trợ? – Canopus

46

C99 có __func__, nhưng đối với C++, đây sẽ là trình biên dịch cụ thể. Về mặt tích cực, một số phiên bản dành riêng cho trình biên dịch cung cấp thông tin kiểu bổ sung, đặc biệt tốt đẹp khi bạn truy tìm bên trong một hàm/lớp templatized.

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

thư viện Boost đã xác định vĩ mô BOOST_CURRENT_FUNCTION đối với hầu hết các trình biên dịch C++ trong tiêu đề boost/current_function.hpp. Nếu trình biên dịch quá cũ để hỗ trợ điều này, kết quả sẽ là "(không xác định)".

3

tôi sẽ nói rằng tôi không biết về bất kỳ điều như vậy nhưng sau đó tôi thấy những câu trả lời khác ...

Nó có thể bạn quan tâm để biết rằng một hồ sơ thực hiện (như gprof) thực hiện chính xác những gì bạn đang hỏi về - nó theo dõi lượng thời gian thực hiện từng chức năng. Một profiler về cơ bản hoạt động bằng cách ghi lại con trỏ lệnh (IP), địa chỉ của lệnh thực hiện hiện tại, mỗi 10ms hoặc hơn. Sau khi chương trình được thực hiện xong, bạn gọi một bộ xử lý sau kiểm tra danh sách các IP và chương trình, và chuyển đổi các địa chỉ đó thành các tên hàm. Vì vậy, tôi muốn đề nghị chỉ sử dụng con trỏ hướng dẫn, chứ không phải là tên hàm, cả hai vì nó dễ dàng hơn để mã và bởi vì nó hiệu quả hơn để làm việc với một số duy nhất hơn với một chuỗi.

+1

Lưu ý rằng để thực hiện điều này, bạn cũng phải lưu địa chỉ tải hình ảnh của thư viện/thư viện thực thi, nếu không bạn có thể không giải thích được các địa chỉ được ghi lại một cách có ý nghĩa. Ngoài ra, trình biên dịch hỗ trợ cho các trình biên tập tùy chỉnh (ví dụ: _penter/_pexit trong MSVC) có thể thay thế cho việc lấy mẫu định kỳ. – bk1e

Các vấn đề liên quan