当前位置: 代码迷 >> 综合 >> 一段项目开发时候用的调试代码 一 --输出特殊信息
  详细解决方案

一段项目开发时候用的调试代码 一 --输出特殊信息

热度:27   发布时间:2024-01-20 02:38:05.0

有的时候在debug项目时候不能直观的使用调试来查询一些状态,而需要自己写一些辅助代码来检测程序的状态(如开发动态库或者COM组件给第三方程序调用无法使用调试器的环境下等)。

1) 以下是一个可以嵌入在代码中的辅助模块,基于标准C++11编写。

2)只有在Debug模式下才能使用,在非Release下改代码会被编译器过滤。(有些特殊情况需要在Release版本中需要编译可以使用宏开启)

3)使用了面向对象的单态模式(Singleton)来实现,并且使用了std::mutex实现了线程安全

4)   并未考虑高符合量的时候的输出,只适合调试轻量级的调试消息代码。

5)高负荷的情况,可以考虑使用队列缓存+线程异步写入,可能需要构建一个完整的log类。但log类可能会有项目依赖,本测试代码并不依赖具体项目可以嵌入到任何C++项目中来作为一种辅助工具使用


代码如下

UT_testlog.h

/*TestLog module header file
This module is designed to support to analyze the code and output the debug log info for the final ocx library.
*/#ifndef UT_TESTLOG_H
#define UT_TESTLOG_H#define TEST_LOG	0//The test flag to enabled the test function in Release version.//define the macro which could be used by the other module of the projects.
#if ((defined(DEBUG) || (TEST_LOG)))
#define DebugCode( code_fragment ) { code_fragment }
#else
#define DebugCode( code_fragment ) 
#endif#include <mutex>
#include <iostream>
#include <string> class  UT_TestLog
{
public:static UT_TestLog* GetInstance();static void Destory();void printlogA(const char* str);void printlogW(const wchar_t* str);void printlogUTF8(const char* str);void printlnlogA(const char* str);void printlnlogW(const wchar_t* str);void printlnlogUTF8(const char* str);private://Save the stream to file.void streamOut(const char* str);void streamOutLn(const char* str);void checkAppendStatus();void clearTextContext();UT_TestLog();//Static variable.static UT_TestLog*	m_pInstance;static std::mutex	mut;bool				m_bIsAppend;
};#endif



UT_testlog.cpp

/*TestLog module source file
This module is designed to support to analyze the code and output the debug log info for the final ocx library.
*/
//This module is validate only in Debug mode.#include "ut_testlog.h"#if ((defined(DEBUG) || (TEST_LOG)))
#include <fstream> 
#include <sstream>static const char logFileName[] = "test.log";
static const char appendTag[] = "[APPEND]";UT_TestLog* UT_TestLog::m_pInstance = NULL;
std::mutex UT_TestLog::mut;UT_TestLog::UT_TestLog() : m_bIsAppend(false)
{
}UT_TestLog* UT_TestLog::GetInstance()
{if(NULL == m_pInstance){m_pInstance = new UT_TestLog();m_pInstance->checkAppendStatus();m_pInstance->clearTextContext();}return m_pInstance;
}void UT_TestLog::Destory()
{if(m_pInstance){delete m_pInstance;m_pInstance = NULL;}
}void UT_TestLog::printlogA(const char* str)
{//Thread safe.std::lock_guard<std::mutex> guard(mut);		streamOut(str);
}void UT_TestLog::printlnlogA(const char* str)
{//Thread safe.std::lock_guard<std::mutex> guard(mut);streamOutLn(str);
}void UT_TestLog::printlogW(const wchar_t* wstr)
{//Thread safe.std::lock_guard<std::mutex> guard(mut);size_t nlength = wcslen(wstr);char *cstr = new char[nlength];size_t converted = 0;	wcstombs_s(&converted, cstr, nlength, wstr, _TRUNCATE);streamOut(cstr);delete[] cstr;}void UT_TestLog::printlnlogW(const wchar_t* wstr)
{//Thread safe.std::lock_guard<std::mutex> guard(mut);size_t nlength = wcslen(wstr);char *cstr = new char[nlength];size_t converted = 0;wcstombs_s(&converted, cstr, nlength, wstr, _TRUNCATE);streamOutLn(cstr);delete[] cstr;}//Todo: This function is copied from the printlogA, we need to handle the conversation from UTF8 to ANSI string.
void UT_TestLog::printlogUTF8(const char* str)
{//Thread safe.std::lock_guard<std::mutex> guard(mut);//We need to do an conversation from UTF8 to ANSIstreamOut(str);
}void UT_TestLog::printlnlogUTF8(const char* str)
{//Thread safe.std::lock_guard<std::mutex> guard(mut);//We need to do an conversation from UTF8 to ANSIstreamOutLn(str);
}//Private member function.void UT_TestLog::streamOut(const char* str)
{std::ofstream out;out.open(logFileName, std::ios::app);out << str;
}void UT_TestLog::streamOutLn(const char* str)
{std::ofstream out;out.open(logFileName, std::ios::app);out << str << std::endl;
}void UT_TestLog::checkAppendStatus()
{std::ifstream in;char buffer[256];in.open(logFileName, std::ios::in | std::ios::binary);if (!in.is_open()){std::cout << "Error opening file";return;}if (!in.eof())in.getline(buffer, 100);if (strcmp(buffer, appendTag) == 0)m_bIsAppend = true;elsem_bIsAppend = false;
}void UT_TestLog::clearTextContext()
{if (m_bIsAppend)	//Append Mode we don't need to clear the string.return;std::ofstream out;out.open(logFileName, std::ios::out | std::ios::binary | std::ios::trunc);out << "";			//Init the test log with null string.
}
#endif


使用方法

在程序初始化的时候(例如main函数 创建一次实例)

在程序退出的时候 (销毁对象)


以后在任意地方可以调用

  相关解决方案