前一篇讲述了基于Mailslot技术的Log Server的简单实现,可以用CreateFile输出Log打印。然而,处处以CreateFile输出打印不是一个好的办法,这里讲述一个模块化的实现,其原理是定义一个Client类,需要输出打印的地方访问这个类的实例来输出Log打印。
首先,我们来实现这个Client类,头文件如下:
namespace giraffe
{
class GIRAFFE_LOG_CLIENT_DLLEXPORT CGiraffeLogClient
{
public:
CGiraffeLogClient(const char * pszSubrootName = NULL);
~CGiraffeLogClient(void);
private:
unsigned long m_ulLogsCount;
std::list<std::string> m_listWriting;
std::list<std::string> m_listCaching;
public:
int Output(const char * s);
int Output(std::string & s);
static DWORD __stdcall WritingProc(void * param);
private:
HANDLE m_hSendMailSlot;
CRITICAL_SECTION m_csCaching;
HANDLE m_hWritingThread;
DWORD m_dwWritingThreadID;
int InitMailslot(void);
int CloseMailslot(void);
std::string m_strRootName;
std::string m_chrIndexAfter;
std::string m_chrDateAfter;
public:
int Writing(void);
HANDLE & GetWaitingHandle(void) { return m_hWaitingEvent; };
int SetPrefixFormat(std::string & format);
private:
HANDLE m_hWaitingEvent;
};
int GIRAFFE_LOG_CLIENT_DLLEXPORT OutputLogString (const char * );
int GIRAFFE_LOG_CLIENT_DLLEXPORT OutputLogString (std::string & );
int GIRAFFE_LOG_CLIENT_DLLEXPORT SetPrefixFormat (std::string & );
}
实现cpp文件。代码如下:
#include "singleton.h"
using namespace giraffe;
//构造函数
CGiraffeLogClient::CGiraffeLogClient(const char * pszSubrootName)
: m_hSendMailSlot(INVALID_HANDLE_VALUE)
, m_ulLogsCount(0)
, m_hWritingThread(NULL)
, m_dwWritingThreadID(0)
, m_hWaitingEvent(NULL)
{
m_strRootName = GIRAFFE_LOG_SERVER_NAME;
if (pszSubrootName && *pszSubrootName) {
// 参数化mailslot文件名称
pszSubrootName = pszSubrootName + strspn(pszSubrootName, " \t,;\\/");
if (pszSubrootName && *pszSubrootName) {
std::string subroot = pszSubrootName;
if (subroot.find_first_of("!^$| \t\n\r,;\"'()[]{}/\\?") != std::string::npos) {
subroot.erase(subroot.find_first_of("!^$| \t\n\r,;\"'()[]{}/\\?") + 0);
}
m_strRootName = "\\\\.\\mailslot\\";
m_strRootName += subroot;
}
} else {
// 从环境变量获取mailslot文件名称
char buffer[256] = {0};
GetEnvironmentVariable("girafferoot", buffer, sizeof(buffer) - 1);
if (buffer[0]) {
m_strRootName &
首先,我们来实现这个Client类,头文件如下:
namespace giraffe
{
class GIRAFFE_LOG_CLIENT_DLLEXPORT CGiraffeLogClient
{
public:
CGiraffeLogClient(const char * pszSubrootName = NULL);
~CGiraffeLogClient(void);
private:
unsigned long m_ulLogsCount;
std::list<std::string> m_listWriting;
std::list<std::string> m_listCaching;
public:
int Output(const char * s);
int Output(std::string & s);
static DWORD __stdcall WritingProc(void * param);
private:
HANDLE m_hSendMailSlot;
CRITICAL_SECTION m_csCaching;
HANDLE m_hWritingThread;
DWORD m_dwWritingThreadID;
int InitMailslot(void);
int CloseMailslot(void);
std::string m_strRootName;
std::string m_chrIndexAfter;
std::string m_chrDateAfter;
public:
int Writing(void);
HANDLE & GetWaitingHandle(void) { return m_hWaitingEvent; };
int SetPrefixFormat(std::string & format);
private:
HANDLE m_hWaitingEvent;
};
int GIRAFFE_LOG_CLIENT_DLLEXPORT OutputLogString (const char * );
int GIRAFFE_LOG_CLIENT_DLLEXPORT OutputLogString (std::string & );
int GIRAFFE_LOG_CLIENT_DLLEXPORT SetPrefixFormat (std::string & );
}
实现cpp文件。代码如下:
#include "singleton.h"
using namespace giraffe;
//构造函数
CGiraffeLogClient::CGiraffeLogClient(const char * pszSubrootName)
: m_hSendMailSlot(INVALID_HANDLE_VALUE)
, m_ulLogsCount(0)
, m_hWritingThread(NULL)
, m_dwWritingThreadID(0)
, m_hWaitingEvent(NULL)
{
m_strRootName = GIRAFFE_LOG_SERVER_NAME;
if (pszSubrootName && *pszSubrootName) {
// 参数化mailslot文件名称
pszSubrootName = pszSubrootName + strspn(pszSubrootName, " \t,;\\/");
if (pszSubrootName && *pszSubrootName) {
std::string subroot = pszSubrootName;
if (subroot.find_first_of("!^$| \t\n\r,;\"'()[]{}/\\?") != std::string::npos) {
subroot.erase(subroot.find_first_of("!^$| \t\n\r,;\"'()[]{}/\\?") + 0);
}
m_strRootName = "\\\\.\\mailslot\\";
m_strRootName += subroot;
}
} else {
// 从环境变量获取mailslot文件名称
char buffer[256] = {0};
GetEnvironmentVariable("girafferoot", buffer, sizeof(buffer) - 1);
if (buffer[0]) {
m_strRootName &