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

有的时候在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 ANSI
	
	streamOut(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 ANSI

	streamOutLn(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;
	else
		m_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函数 创建一次实例)

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


以后在任意地方可以调用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值