บทนำ
นักพัฒนามักพบว่าตนเองต้องการกลไกการบันทึกที่เชื่อถือได้เพื่อใช้ในการดีบัก อย่างไรก็ตาม การรักษาประสิทธิภาพของโค้ดในระหว่างการผลิตอาจเป็นเรื่องท้าทาย โดยเฉพาะเมื่อการบันทึกที่มีรายละเอียดมากอาจส่งผลกระทบต่อประสิทธิภาพ คำถามทั่วไปเกิดขึ้น: คุณจะสร้างฟังก์ชันที่ใช้สำหรับการดีบักซึ่งสนับสนุนรายการอาร์กิวเมนต์ตัวแปรคล้ายกับ printf()
ได้อย่างไร?
ในบล็อกโพสต์นี้ เราจะสำรวจวิธีการที่ตรงไปตรงมาซึ่งใช้คำสั่งของโปรเซสเซอร์ใน C/C++ เพื่อสร้างฟังก์ชันการบันทึกที่สามารถลบออกในระหว่างการปรับแต่งประสิทธิภาพ ในขณะเดียวกันก็รักษาความยืดหยุ่นของข้อมูลนำเข้าได้
การสร้างฟังก์ชัน Debug Logging
ขั้นตอนที่ 1: กำหนดลายเซ็นฟังก์ชัน
เราต้องการให้ฟังก์ชันการบันทึกของเรารับสตริงรูปแบบและจำนวนอาร์กิวเมนต์ที่แตกต่างกัน ฟังก์ชันลายเซ็นแบบ printf
ช่วยให้เราสามารถจัดรูปแบบสตริงได้อย่างไดนามิก ด้านล่างคือโครงสร้างกระดูกสันหลังพื้นฐานของฟังก์ชันที่ต้องการ:
void XTrace(LPCTSTR lpszFormat, ...);
ขั้นตอนที่ 2: การใช้ตัวแปรอาร์กิวเมนต์
เพื่อให้ได้ฟังก์ชันการทำงานของอาร์กิวเมนต์ตัวแปร เราสามารถใช้แมโคร va_list
, va_start
และ va_end
ที่มีอยู่ในไลบรารีมาตรฐาน C สิ่งนี้ช่วยให้เราสามารถประมวลผลอาร์กิวเมนต์ที่ส่งไปยัง XTrace
นี่คือวิธีที่คุณสามารถนำไปใช้:
#include <stdio.h>
void XTrace(LPCTSTR lpszFormat, ...) {
va_list args;
va_start(args, lpszFormat);
int nBuf;
TCHAR szBuffer[512]; // คิดเกี่ยวกับการใช้การจัดสรรแบบไดนามิกแทน
nBuf = _vsnprintf(szBuffer, 511, lpszFormat, args);
::OutputDebugString(szBuffer);
va_end(args);
}
ส่วนสำคัญของโค้ด:
va_list args
: ใช้ในการจัดเก็บรายการอาร์กิวเมนต์va_start(args, lpszFormat)
: ใช้ในการเริ่มต้นargs
เพื่อนำค่าอาร์กิวเมนต์หลังlpszFormat
_vsnprintf
: ฟังก์ชันนี้จัดรูปแบบสตริงโดยใช้รายการอาร์กิวเมนต์และเขียนไปยังบัฟเฟอร์OutputDebugString
: ส่งผลลัพธ์สตริงที่จัดรูปแบบไปยังหน้าต่างเอาต์พุตของดีบักเกอร์
ขั้นตอนที่ 3: การสร้างคอมไพล์เงื่อนไข
เพื่อให้แน่ใจว่าฟังก์ชันการดีบักจะถูกลบออกในระหว่างการปรับแต่งประสิทธิภาพ เราสามารถใช้คำสั่งโปรเซสเซอร์ โดยการกำหนดแมโครตามธงการดีบัก เราสามารถควบคุมได้ว่าฟังก์ชันการบันทึกของเราจะรวมอยู่ด้วยหรือไม่
การตั้งค่าสำหรับตัวอย่าง:
#ifdef _DEBUG
#define XTRACE XTrace
#else
#define XTRACE
#endif
- แมโคร
XTRACE
จะชี้ไปยังฟังก์ชันXTrace
ที่แท้จริงเมื่อคอมไพล์ในโหมดดีบัก ในการปรับแต่งประสิทธิภาพ (เมื่อไม่กำหนด_DEBUG
),XTRACE
จะกลายเป็นคำสั่งว่าง ส่งผลให้ลบโค้ดบันทึกการดีบักออกไปอย่างมีประสิทธิภาพ
การรวมทุกอย่างเข้าด้วยกัน
นี่คือการนำไปใช้ทั้งหมดเพื่อความชัดเจน:
#include <stdio.h>
#include <stdarg.h>
#include <Windows.h> // หรือ <Linux/string.h> ขึ้นอยู่กับแพลตฟอร์ม
void XTrace0(LPCTSTR lpszText) {
::OutputDebugString(lpszText);
}
void XTrace(LPCTSTR lpszFormat, ...) {
va_list args;
va_start(args, lpszFormat);
int nBuf;
TCHAR szBuffer[512];
nBuf = _vsnprintf(szBuffer, 511, lpszFormat, args);
::OutputDebugString(szBuffer);
va_end(args);
}
#ifdef _DEBUG
#define XTRACE XTrace
#else
#define XTRACE
#endif
ตอนนี้คุณสามารถใช้แมโคร XTRACE
ในโค้ดของคุณได้ดังนี้:
XTRACE("Warning: value %d > 3!\n", value);
สรุป
การสร้างฟังก์ชันการบันทึกที่ใช้สำหรับดีบักใน C/C++ ที่สามารถรับตัวแปรอาร์กิวเมนต์ไม่เพียง แต่สามารถทำได้ แต่ยังสามารถจัดการได้อย่างมีประสิทธิภาพโดยใช้คำสั่งโปรเซสเซอร์ เทคนิคนี้ช่วยให้โค้ดการผลิตของคุณสะอาดและมีประสิทธิภาพ
ตอนนี้คุณสามารถดีบักแอปพลิเคชันของคุณอย่างมีประสิทธิภาพโดยไม่กระทบต่อประสิทธิภาพในสภาพแวดล้อมการผลิต!