在window10安装vs2013编译,调试程序 出现以下错误代码 warning C4251: “LogManagerSingleton::_streamStack”: class“std::stack<LogStream *,std::deque<_Ty,std::allocator<_Ty>>>”需要有 dll 接口由 class“LogManagerSingleton”的客户端使用
给出解释并修正方案 下面是代码:
// Copyright (C) 1991 - 1999 Rational Software Corporation
#if defined (_MSC_VER) && (_MSC_VER >= 1000)
#pragma once
#endif
#ifndef _INC_LOGMANAGERSINGLETON_4112E32B0157_INCLUDED
#define _INC_LOGMANAGERSINGLETON_4112E32B0157_INCLUDED
#include <stack>
//定义Enable操作是否可以Register新的LOG
//#define _ENABLE_WITH_NEW
class LogSwitchBox;
class LogLeaf;
class LogStream;
class LogStreamSimpleFile;
/**
*日志记录管理者,单件模式
*/
class _Foundation_Export_ LogManagerSingleton
{
public:
LogSwitchBox* GetRoot() const;
// Destructor
virtual ~LogManagerSingleton();
bool RegisterLog(const std::string path );
//!压入一个stream,以后创建流就用这个创建
void PushStream(LogStream* stream);
//!弹出一个stream
LogStream* PopStream(void);
static LogManagerSingleton* getInstance();
static void Cleanup(void);
protected:
LogStream* CreateStream(const std::string& name,const std::string& fullPath);
// Constructor
LogManagerSingleton();
LogSwitchBox* _root;
std::stack<LogStream*> _streamStack;
private:
static LogManagerSingleton* uniqueInstance;
public:
int Report(const std::string path,std::string desc);
int Report(const std::string path,std::string desc,long num);
// 设置节点或者叶子的状态
void Enable(const std::string path,bool enable);
};
//
#define LOG_PUSHSTREAM(ptr) LogManagerSingleton::getInstance()->PushStream(ptr)
#define LOG_POPSTREAM() LogManagerSingleton::getInstance()->PopStream()
#define LOG_REPORTNUM(path,desc,num) LogManagerSingleton::getInstance()->Report(path,desc,num)
#define LOG_REPORT(path,desc) LogManagerSingleton::getInstance()->Report(path,desc)
#define LOG_ENABLE(path,enable) LogManagerSingleton::getInstance()->Enable(path,enable)
#define LOG_REGISTER(path) LogManagerSingleton::getInstance()->RegisterLog(path)
#define LOG_CLEANUP() do{/*delete LogManagerSingleton::getInstance()*/LogManagerSingleton::Cleanup();}while(0)
extern "C"
{
void _Foundation_Export_ LOG_REPORTVAR(const char* path,const char* pszString,...);
void _Foundation_Export_ LOG_ASSERT(bool exp,const char* pszString,...);
}
extern "C"
{
void _Foundation_Export_ LOG_DEBUG_REPORT(const char* path,const char* pszString,...);
}
#endif /* _INC_LOGMANAGERSINGLETON_4112E32B0157_INCLUDED */
// Copyright (C) 1991 - 1999 Rational Software Corporation
#include "stdafx.h"
#include "LogManagerSingleton.h"
#include "LogSwitchBox.h"
#include "LogLeaf.h"
#include "LogStream.h"
#include "LogStreamSimpleFile.h"
LogManagerSingleton* LogManagerSingleton::uniqueInstance=0;
LogStream* LogManagerSingleton::CreateStream(const std::string& name,const std::string& fullPath)
{
if (_streamStack.size() > 0)
{
LogStream* stream = _streamStack.top();
return stream->CreateStream(name,fullPath);
}
return new LogStreamSimpleFile(name,fullPath);
}
bool LogManagerSingleton::RegisterLog(const std::string path)
{
// TODO: Add your specialized code here.
std::string opPath = path;
if(opPath[0] != '/')
return false;
std::string fullPath=opPath;
std::string childName;
std::string tempStr=opPath;
LogSwitchBox* parent=_root,*child=0;
int offset=0,offsetEnd=0;
opPath=opPath.c_str()+1;//去掉'/'
for(;;)
{
offset=static_cast<int>(opPath.find('/'));
if(-1 != offset)
{//非叶子
childName="";
childName.append(opPath.c_str(),offset);
opPath=opPath.c_str()+offset+1;//去掉childName/
child=(LogSwitchBox*)(parent->FindChildByName(childName));
if(!child)
{
child=new LogSwitchBox(childName);
parent->AddChild(child);
}
parent=child;
}
else
{//叶子
//childName=""
childName=opPath;
LogCtrl* leaf=parent->FindChildByName(childName);
if(!leaf)
{//无同名叶子
LogStream* stream=CreateStream(childName,fullPath);
leaf=new LogLeaf(childName,stream);
parent->AddChild(leaf);
return true;
}
else
{
LogStream* stream=CreateStream(childName,fullPath);
((LogLeaf*)leaf)->ChangeStream(stream);
}
return true;
}
if(opPath.empty())
return true;
}
}
LogManagerSingleton* LogManagerSingleton::getInstance()
{
// TODO: Add your specialized code here.
// NOTE: Requires a correct return value to compile.
if(uniqueInstance)
{
return uniqueInstance;
}
else
{
uniqueInstance=new LogManagerSingleton;
return uniqueInstance;
}
}
void LogManagerSingleton::Cleanup(void)
{
if (uniqueInstance)
{
delete uniqueInstance;
uniqueInstance = 0;
}
}
LogManagerSingleton::LogManagerSingleton() : _root(0)
{
// ToDo: Add your specialized code here and/or call the base class
_root=new LogSwitchBox(std::string("/"));
}
LogManagerSingleton::~LogManagerSingleton()
{
// ToDo: Add your specialized code here and/or call the base class
_root->Flush();
delete _root;
_root=0;
LogStream* stream = 0;
while (!_streamStack.empty())
{
stream = _streamStack.top();
stream->ReleaseStream();
_streamStack.pop();
}
}
LogSwitchBox* LogManagerSingleton::GetRoot() const
{
return _root;
}
int LogManagerSingleton::Report(const std::string path,std::string desc)
{
if(_root)
_root->Report(path,desc);
return 0;
}
int LogManagerSingleton::Report(const std::string path, std::string desc,long num)
{
char sz[20]={""};
_snprintf(sz,20,"%d",num);
desc.append(sz);
if(_root)
_root->Report(path,desc);
return 0;
}
// 设置节点或者叶子的状态
void LogManagerSingleton::Enable(const std::string path,bool enable)
{
std::string opPath = path;
std::string tempStr,childName;
int offsetStart=0,offsetEnd=0;
LogSwitchBox* parent=_root;
LogCtrl* child=0;
for(;;)
{
if(opPath.empty())
return;
offsetStart=static_cast<int>(opPath.find('/'));
tempStr=opPath.c_str()+1;//去掉第一个'/'
offsetEnd=static_cast<int>(tempStr.find('/'));
if(offsetStart == -1 || -1 == offsetEnd)
{//叶子 第2中情况是opPath为"/xxxxx",也就是根的叶子
if(offsetStart == -1)
childName=opPath;
else
childName=opPath.c_str()+1;
child=parent->FindChildByName(childName);
if(!child)
{
#ifdef _ENABLE_WITH_NEW
LogStream* stream=new LogStreamSimpleFile(childName);
child=new LogLeaf(childName,stream);
parent->AddChild(child);
#else
#ifdef _WIN32
MessageBox(0,opPath.c_str(),"LOG PATH NOT FOUND",MB_OK);
#endif
return;
#endif
}
child->Enable(enable);
return;
}
else
{//非叶子
childName="";
childName.append(tempStr.c_str(),offsetEnd);
child=parent->FindChildByName(childName);
if(!child)
{
#ifdef _ENABLE_WITH_NEW
child=new LogSwitchBox(childName);
parent->AddChild(child);
#else
return;
#endif
}
opPath=tempStr.c_str()+1+offsetEnd;
parent=(LogSwitchBox*)child;
continue;
}
}
}
void LogManagerSingleton::PushStream(LogStream* stream)
{
_streamStack.push(stream);
}
LogStream* LogManagerSingleton::PopStream(void)
{
if (_streamStack.size() > 0)
{
LogStream* stream = _streamStack.top();
_streamStack.pop();
return stream;
}
return 0;
}
void LOG_REPORTVAR(const char* path,const char* pszString,...)
{
char szDesc[1024*32]; //修改Log长度为1024
va_list va;
va_start(va, pszString);
#ifdef _WIN32
StringCbVPrintf(szDesc, 1024*32, pszString, va); //修改Log长度为1024
#else
wvsprintf( szDesc, pszString, va );
#endif
va_end(va);
LOG_REPORT(path, szDesc);
}
void LOG_ASSERT(bool exp,const char* pszString,...)
{
if (!exp)
{
char szDesc[256]; //修改Log长度为1024
va_list va;
va_start(va, pszString);
#ifdef _WIN32
StringCbVPrintf(szDesc, 256, pszString, va); //修改Log长度为1024
#else
wvsprintf( szDesc, pszString, va );
#endif
va_end(va);
//MessageBox(0,szDesc,"Assert",MB_OK);
//LOG_REPORT("/Foundation/Assert", szDesc);
}
}
#ifdef _DEBUG
void LOG_DEBUG_REPORT(const char* path,const char* pszString,...)
{
char szDesc[1024*32];
va_list va;
va_start( va, pszString );
#ifdef _WIN32
StringCbVPrintf( szDesc,1024*32, pszString, va );
#else
wvsprintf( szDesc, pszString, va );
#endif
va_end( va );
LOG_REPORT(path,szDesc);
}
#else
void LOG_DEBUG_REPORT(const char* path,const char* pszString,...)
{
}
#endif