现在已经是大学生涯的最后阶段了,回首过去的四年真是充满感慨。由于毕业设计早早完事以至于现在略显无聊,呵呵。但是一直都没闲着,最近在研究内存管理方面的东西,参考了不少的书,有IBM出的那本《C++应用程序性能与优化》、《深入解析Windows操作系统》、《Windows核心编程》等等。目的就是想对Windows的内存管理策略以及Windows下面使用C++编程如何更好的使用内存有更深入和更清醒的认识。另外在这些积累之后可能会研究一下内存池技术。
前两天为老师做一个Demo,中间写了一些简单的辅助代码,没什么用,发这儿留个纪念,聊胜于无。
/**///////////////////////////////////////////////////////////////////////////// 版权所有 董波
/**///////////////////////////////////////////////////////////////////////////// File : Buffer.h
// Author: Dongbo
// Date: 2009.1.14
// Description: 对动态分配内存的包装以提供更高更好的安全性
/**///////////////////////////////////////////////////////////////////////////#ifndef _DB_BUFFER_H_
#define _DB_BUFFER_H_
#include <cassert>
/**//*
适用情况:
需要动态分配内存,且需要兼容原有API的时候!此时auto_ptr并不适用!
*/
namespace db
{
// 基本实现细节
namespace detail
{
// Base_Buffer
template < typename _Ty >
class Base_Buffer
{
private:
Base_Buffer( const Base_Buffer<_Ty>& );
Base_Buffer& operator = ( const Base_Buffer<_Ty>& );
public:
Base_Buffer( unsigned uCount ):m_pTmp(0),m_uCount( uCount )
{
if( 0 != uCount )
{
m_pTmp = new _Ty[uCount];
}
}
~Base_Buffer()
{
if( 0 != m_pTmp )
{
delete []m_pTmp;
m_pTmp = 0;
}
}
_Ty* GetBufPtr()
{
assert( 0 != m_pTmp );
return m_pTmp;
}
const _Ty* GetBufPtr() const
{
assert( 0 != m_pTmp );
return m_pTmp;
}
unsigned GetCount() const
{
return m_uCount;
}
// 2009.1.20添加 增加重设功能
void ReSize( unsigned uSize )
{
if( 0 != uSize )
{
if( 0 != m_pTmp )
{
delete []m_pTmp;
m_pTmp = NULL;
}
m_pTmp = new _Ty[ uSize ];
m_uCount = uSize;
}
}
protected:
_Ty* m_pTmp;
unsigned m_uCount;
};
}
template < typename _Ty >
class Buffer : public detail::Base_Buffer< _Ty >
{
public:
Buffer( unsigned uCount ) : detail::Base_Buffer<_Ty>(uCount)
{
}
};
class ByteBuffer : public Buffer<char>
{
public:
ByteBuffer( unsigned uSize ) : Buffer<char>(uSize)
{ }
public:
unsigned GetBytesNum() const
{
return Buffer<char>::m_uCount;
}
};
typedef ByteBuffer CharBuffer;
}
endif // #ifndef _DB_BUFFER_H_
/**///////////////////////////////////////////////////////////////////////////// 版权所有 董波
/**///////////////////////////////////////////////////////////////////////////// File : string_cast.h
// Author: Dongbo
// Date: 2009.1.16
// Description: char字符串与wchar_t字符串之间的转换
/**///////////////////////////////////////////////////////////////////////////#ifndef _DB_STRING_CAST_H_
#define _DB_STRING_CAST_H_
#include <string>
#include <cstdlib>
#include "Buffer.h"
namespace db
{
// 几乎从来不用,用于扩展!
template < typename _Ty >
class string_cast
{
private:
string_cast();
template < typename _Dummy >
string_cast& operator = ( const string_cast<_Dummy>& );
template < typename _Dummy >
string_cast( const string_cast<_Dummy>& );
};
// 到wchar_t字符串的转换
template <>
class string_cast< wchar_t >
{
private:
// 避免产生一些奇怪的语法!
string_cast();
template < typename _Dummy >
string_cast& operator = ( const string_cast<_Dummy>& );
template < typename _Dummy >
string_cast( const string_cast<_Dummy>& );
public:
template < typename _TCHAR >
string_cast( const _TCHAR* str )
{
if( NULL == str )
{
throw std::bad_cast( "目标串为空" );
}
m_strBuf = str;
}
template <>
string_cast( const char* str )
{
// 检查指针状态
if( NULL == str )
{
throw std::bad_cast( "目标串为空" );
}
// 获取长度以创建缓冲区
unsigned iLength = strlen( str ) + 1;
Buffer<wchar_t> buffer( iLength );
// 修改现场以支持中文
setlocale( LC_CTYPE, "chs" );
// 转换
size_t iSize = 0;
#if _MSC_VER > 1310
mbstowcs_s( &iSize, buffer.GetBufPtr(), iLength, str, iLength );
#else
mbstowcs( buffer.GetBufPtr(), str, iLength );
#endif
// 还原现场
setlocale( LC_CTYPE, "" );
// 基本错误检查
if( (iSize<<1) < iLength )
{
throw std::bad_cast( "转换未完成" );
}
// 拷贝到字符串中
m_strBuf.assign( buffer.GetBufPtr() );
}
// 获取结果!
operator std::wstring() const
{
return m_strBuf;
}
public:
const std::wstring& ToWstr() const
{
return m_strBuf;
}
protected:
std::wstring m_strBuf;
};
// 向string的转换
template<>
class string_cast< char >
{
private:
string_cast();
template < typename _Dummy >
string_cast& operator = ( const string_cast<_Dummy>& );
template < typename _Dummy >
string_cast( const string_cast<_Dummy>& );
public:
template < typename _TCHAR >
string_cast( const _TCHAR* str )
{
if( NULL == str )
{
throw std::bad_cast( "目标串为空" );
}
m_strBuf = str;
}
template <>
string_cast( const wchar_t* str )
{
if( NULL == str )
{
throw std::bad_cast( "目标串为空" );
}
unsigned iLength = ( wcslen( str ) + 1 )<<1;
CharBuffer buffer( iLength );
// 修改现场以支持中文
setlocale( LC_CTYPE, "chs" );
size_t iSize = 0;
#if _MSC_VER > 1310
wcstombs_s( &iSize, buffer.GetBufPtr(), iLength, str, iLength );
#else
wcstombs( buffer.GetBufPtr(), str, iLength );
#endif
setlocale( LC_CTYPE, "" );
if( (iSize<<1) < iLength )
{
throw std::bad_cast( "转换未完成" );
}
m_strBuf.assign( buffer.GetBufPtr() );
}
operator std::string() const
{
return m_strBuf;
}
public:
const std::string& ToStr() const
{
return m_strBuf;
}
protected:
std::string m_strBuf;
};
}
#endif // #ifndef _DB_STRING_CAST_H_
上面是两个字符串转化的程序,其实还可以优化的,只不过,我很懒的,呵呵。
#pragma once
/**///////////////////////////////////////////////////////////////////////////// FILE : DynLib.h
// Author : Dongbo
// Created: 2009.5.13
// Desc : Encapsulation for dynamic library!
/**///////////////////////////////////////////////////////////////////////////
#include <string>
#include <Windows.h>
#include <tchar.h>
namespace db
{
class CDynLib
{
public:
typedef std::basic_string< TCHAR > string_type;
typedef HMODULE handle_type;
public:
CDynLib( const string_type& strDynLibName );
~CDynLib();
public:
void Load();
void UnLoad();
const string_type& GetDynLibName() const;
void* GetProc( const std::string& strSymbol ) const;
public:
static string_type GetSysErrorMsg( unsigned uCode );
protected:
string_type m_strDynLibName;
handle_type m_hHandle;
};
inline const CDynLib::string_type& CDynLib::GetDynLibName() const
{
return this->m_strDynLibName;
}
}
/**///////////////////////////////////////////////////////////////////////////// FILE : DynLib.cpp
// Author : Dongbo
// Created: 2009.5.13
// Desc : Encapsulation for dynamic library!
/**///////////////////////////////////////////////////////////////////////////
#ifdef __DB_USE_MFC_APPLICATION__
#include "stdafx.h"
#endif // #ifdef __DB_USE_MFC_APPLICATION__
#include "DynLib.h"
#include "string_cast.h"
namespace db
{
CDynLib::CDynLib( const string_type& strDynLibName ) : \
m_strDynLibName( strDynLibName ), m_hHandle( 0 )
{
}
CDynLib::~CDynLib()
{
}
CDynLib::string_type CDynLib::GetSysErrorMsg( unsigned uCode )
{
// 这里的uCode被定义为从GetLastError获得的返回值
LPVOID lpMsgBuf;
::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
uCode,
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
(LPTSTR)&lpMsgBuf,
0,
NULL
);
string_type strMsg( (string_type::value_type*)lpMsgBuf );
::LocalFree( lpMsgBuf );
return strMsg;
}
void CDynLib::Load()
{
m_hHandle = ::LoadLibrary( this->m_strDynLibName.c_str() );
if( 0 == m_hHandle )
{
// 因为runtime_error不能接受wchar_t的字符串
// 当系统使用的是char的时候,string_cast只起垫片的作用
throw std::runtime_error(
"加载动态链接库:" +
(db::string_cast<char>( this->m_strDynLibName.c_str() )).ToStr() +
"失败,信息:" +
(db::string_cast<char>( CDynLib::GetSysErrorMsg( ::GetLastError() ).c_str() )).ToStr() );
}
}
void CDynLib::UnLoad()
{
if( 0 != m_hHandle )
{
// 忽略卸载的错误
::FreeLibrary( m_hHandle );
m_hHandle = 0;
}
}
void* CDynLib::GetProc( const std::string& strSymbol ) const
{
assert( m_hHandle != 0 );
return (void*)::GetProcAddress( this->m_hHandle, strSymbol.c_str() );
}
}
#pragma once
/**///////////////////////////////////////////////////////////////////////////// FILE : Singleton.h
// Author : Dongbo
// Created: 2009.5.13
// Desc : Singleton template
/**///////////////////////////////////////////////////////////////////////////
#include <cassert>
namespace db
{
template < typename T >
class Singleton
{
protected:
static T ms_Singleton;
protected:
Singleton()
{
}
~Singleton()
{
}
public:
static T& GetSingleton()
{
return ms_Singleton;
}
static T* GetSingletonPtr()
{
return &ms_Singleton;
}
};
}
#pragma once
/**///////////////////////////////////////////////////////////////////////////// FILE : DynLibManager.h
// Author : Dongbo
// Created: 2009.5.13
// Desc : A Manager for dynlib
/**///////////////////////////////////////////////////////////////////////////
#include "Singleton.h"
#include "DynLib.h"
#include <map>
namespace db
{
class CDynLibManager : public db::Singleton< CDynLibManager >
{
public:
typedef db::Singleton< CDynLibManager > base_class;
typedef db::CDynLib dynlib_type;
typedef dynlib_type::string_type string_type;
typedef std::map< string_type, dynlib_type* > dynlib_container;
typedef CDynLibManager my_type;
typedef CDynLibManager& my_reference;
typedef CDynLibManager* my_pointer;
friend class base_class;
protected:
CDynLibManager();
~CDynLibManager();
public:
bool RegisterDynLib( const string_type& strDynLibName );
void UnRegisterDynLib( const string_type& strDynLibName );
const dynlib_type& GetDynLib( const string_type& strDynLibName ) const;
protected:
dynlib_container m_lstDynlibs;
};
}
/**///////////////////////////////////////////////////////////////////////////// FILE : DynLibManager.cpp
// Author : Dongbo
// Created: 2009.5.13
// Desc : A Manager for dynlib
/**///////////////////////////////////////////////////////////////////////////
#ifdef __DB_USE_MFC_APPLICATION__
#include "stdafx.h"
#endif // #ifdef __DB_USE_MFC_APPLICATION__
#include "DynLibManager.h"
namespace db
{
template<>
CDynLibManager Singleton<CDynLibManager>::ms_Singleton;
CDynLibManager::CDynLibManager()
{
}
CDynLibManager::~CDynLibManager()
{
for( dynlib_container::iterator it = m_lstDynlibs.begin();
it != m_lstDynlibs.end();
++it )
{
if( it->second )
{
it->second->UnLoad();
delete it->second;
}
}
m_lstDynlibs.clear();
}
bool CDynLibManager::RegisterDynLib( const string_type& strDynLibName )
{
if( m_lstDynlibs.find( strDynLibName ) != m_lstDynlibs.end() )
{
return true;
}
else
{
// 重新载入
dynlib_type* pTmp = new dynlib_type(strDynLibName);
if( !pTmp )
{
return false;
}
try
{
pTmp->Load();
}
catch( std::runtime_error&
#if defined(DEBUG) || defined(_DEBUG)
e
#endif // #if defined(DEBUG) || defined(_DEBUG)
)
{
delete pTmp;
#if defined(DEBUG) || defined(_DEBUG)
throw e;
#else
return false;
#endif // #if defined(DEBUG) || defined(_DEBUG)
}
m_lstDynlibs.insert( std::make_pair( strDynLibName, pTmp ) );
return true;
}
}
void CDynLibManager::UnRegisterDynLib( const string_type& strDynLibName )
{
dynlib_container::iterator pos = m_lstDynlibs.find( strDynLibName );
if( pos != m_lstDynlibs.end() )
{
if( pos->second )
{
pos->second->UnLoad();
delete pos->second;
}
m_lstDynlibs.erase( pos );
}
}
const CDynLibManager::dynlib_type& CDynLibManager::GetDynLib( const string_type& strDynLibName ) const
{
dynlib_container::const_iterator pos = m_lstDynlibs.find( strDynLibName );
if( pos != m_lstDynlibs.end() && pos->second )
{
return *pos->second;
}
else
{
throw std::runtime_error( "查找失败!该库可能尚未注册!" );
}
}
}
在程序中我使用这个单件Manager来管理所有的动态载入的dll,目前还没遇到什么问题,当然不能说它没问题,哈哈。
for example:
#include <iostream>
using namespace std;
#include <tchar.h>
#include "DynLibManager.h"
int main()
{
using namespace db;
try
{
CDynLibManager::GetSingletonPtr()->RegisterDynLib( _T("data.dll") );
void *p = CDynLibManager::GetSingletonPtr()->GetDynLib( _T("data.dll") ).GetProc( "QueryDataBaseInterface" );
if( p != NULL )
{
cout<<"加载成功!"<<endl;
}
else
{
cout<<"加载失败!"<<endl;
}
}
catch( std::runtime_error& e )
{
cout<< e.what() << endl;
}
return 0;
}
代码包:
http://ishare.iask.sina.com.cn/f/5180214.html 学生生涯快结束了,大学也快结束了,我对未来充满了向往。我渴望新的生活,渴望新的挑战,渴望结识新的朋友!有朋自远方来不亦悦乎?