不多说了,看代码吧,我们不需要写两套关于wchar_t, char的函数,只需要定义一个模板。这是我想了一个星期创造出来的,应该还没有人这样写吧。
strFuncTypeDef.h 字符串操作函数定义
/* * author: zyb * \brief: strFuncTypeDef for template function */ #pragma once #include<crtdefs.h> /* * <string.h> */ /* * char function type define */ typedef errno_t(__cdecl* strcpy_s_type)(char*, rsize_t, char const*); //not strcpy_s<size> type typedef errno_t(__cdecl* strcat_s_type)(char*, rsize_t, char const*); //not strcat_s<size> type typedef errno_t(__cdecl* strerror_s_type)(char*, size_t, int); //not strerror_s<size> type typedef errno_t(__cdecl* _strerror_s_type)(char*, size_t, char const*); //not _strerror_s<size> type typedef errno_t(__cdecl* strncat_s_type)(char*, rsize_t, char const*, rsize_t); //not strncat_s<size> type typedef errno_t(__cdecl* strncpy_s_type)(char*, rsize_t, char const*, rsize_t); //not strncpy_s<size> type typedef errno_t(__cdecl* _strlwr_s_type)(char*, size_t); //not _strlwr_s<size> type typedef errno_t(__cdecl* _strlwr_s_l_type)(char*, size_t, _locale_t); //not _strlwr_s_l<size> type typedef errno_t(__cdecl* _strnset_s_type)(char*, size_t, int, size_t); //not _strnset_s<size> type typedef errno_t(__cdecl* _strset_s_type)(char*, size_t, int); //not _strset_s<size> type typedef errno_t(__cdecl* _strupr_s_type)(char*, size_t); //not _strupr_s<size> type typedef errno_t(__cdecl* _strupr_s_l_type)(char*, size_t, _locale_t); //not _strupr_s_l<size> type /* * wchar function type define */ typedef errno_t(__cdecl* wcscat_s_type)(wchar_t*, rsize_t, wchar_t const*); //not wcscat_s<size> type typedef errno_t(__cdecl* wcscpy_s_type)(wchar_t*, rsize_t, wchar_t const*); //not wcscpy_s<size> type typedef errno_t(__cdecl* wcsncat_s_type)(wchar_t*, rsize_t, wchar_t const*, rsize_t);//not wcsncat_s<size> type typedef errno_t(__cdecl* wcsncpy_s_type)(wchar_t*, rsize_t, wchar_t const*, rsize_t);//not wcsncpy_s<size> type typedef errno_t(__cdecl* _wcserror_s_type)(wchar_t*, size_t, int); //not _wcserror_s<size> type typedef errno_t(__cdecl* __wcserror_s_type)(wchar_t*, size_t, wchar_t const*); //not __wcserror_s<size> type typedef errno_t(__cdecl* _wcsnset_s_type)(wchar_t*, size_t, wchar_t, size_t); //not _wcsnset_s<size> type typedef errno_t(__cdecl* _wcsset_s_type)(wchar_t*, size_t, wchar_t); //not _wcsset_s<size> type typedef errno_t(__cdecl* _wcslwr_s_type)(wchar_t*, size_t); //not _wcslwr_s<size> type typedef errno_t(__cdecl* _wcslwr_s_l_type)(wchar_t*, size_t, _locale_t); //not _wcslwr_s_l<size> type typedef errno_t(__cdecl* _wcsupr_s_type)(wchar_t*, size_t); //not _wcsupr_s_type<size> type typedef errno_t(__cdecl* _wcsupr_s_l_type)(wchar_t*, size_t, _locale_t); //not _wcsupr_s_l_type<size> type /* * <stdio.h> */ typedef char*(__cdecl* gets_s_type)(char*, rsize_t); //not gets_s<size> type typedef errno_t(__cdecl* tmpnam_s_type)(char*, rsize_t); //not tmpnam_s<size> type typedef int(__CRTDECL* vsprintf_s_type)(char* const, size_t const, char const* const, va_list);//not vsprintf_s<size> type typedef int(__CRTDECL* _vsnprintf_s_type)(char* const, size_t const, size_t const, char const* const, va_list);//not _vsnprintf_s<size> type typedef int(__CRTDECL* vsnprintf_s_type)(char* const, size_t const, size_t const, char const* const, va_list);//not vsnprintf_s<size> type typedef int(__CRTDECL* sprintf_s_type)(char* const, size_t const, char const* const, ...);//not sprintf_s<size> type typedef int(__CRTDECL* _snprintf_s_type)(char* const, size_t const, size_t const, char const* const, ...);//not _snprintf_s<size> type typedef int(__CRTDECL* vsscanf_s_type)(char const* const, char const* const, va_list);//not vsscanf_s<size> type /* * <corecrt_wstdio.h> */ typedef wchar_t*(__cdecl* _getws_s_type)(wchar_t*, size_t); //not _getws_s<size> type typedef errno_t(__cdecl _wtmpnam_s_type)(wchar_t*, size_t); //not _wtmpnam_s<size> type typedef int(__CRTDECL* _vsnwprintf_s_type)(wchar_t* const, size_t const, size_t const, wchar_t const* const, va_list);//not _vsnwprintf_s<size> type typedef int(__CRTDECL* vswprintf_s_type)(wchar_t* const, size_t const, wchar_t const* const, va_list);//not vswprintf_s<size> type typedef int(__CRTDECL* swprintf_s_type)(wchar_t* const, size_t const, wchar_t const* const, ...);//not swprintf_s<size> type typedef int(__CRTDECL* _snwprintf_s_type)(wchar_t* const, size_t const, size_t const, wchar_t const* const, ...);//not _snwprintf_s<size> type typedef int(__CRTDECL* vswscanf_s_type)(wchar_t const* const, wchar_t const* const, va_list);//not vswscanf_s<size> type
makeFuncMacro.h 宏定义:
/* * author: zyb * \brief: make function * \other: still high-performance in Release . because VS is every smart */ #pragma once #define DEC_CHARTYPE(funcName,content) \ template<typename _T> \ struct funcName{}; \ template<> \ struct funcName<char> \ { static inline auto g()->char{ return content; } }; \ template<> \ struct funcName<wchar_t> \ { static inline auto g()->wchar_t{ return L##content; } }; #define DEC_STRTYPE(funcName,content) \ template<typename _T> \ struct funcName{}; \ template<> \ struct funcName<char*> \ { static inline auto g()->char*{ return const_cast<char*>(content); } }; \ template<> \ struct funcName<wchar_t*> \ { static inline auto g()->wchar_t*{ return const_cast<wchar_t*>(L##content); } }; #define DEC_CFUNC1(funcName) \ template<typename _T> \ struct funcName##T{}; \ template<> \ struct funcName##T<char> \ { static inline auto c()->decltype(_##funcName)*{ return _##funcName; } }; \ template<> \ struct funcName##T<wchar_t> \ { static inline auto c()->decltype(_w##funcName)*{ return _w##funcName; } }; #define DEC_SYSFUNC(funcName) \ template<typename _T> \ struct funcName##T{}; \ template<> \ struct funcName##T<char> \ { static inline auto c()->decltype(funcName##A)*{ return funcName##A; } }; \ template<> \ struct funcName##T<wchar_t> \ { static inline auto c()->decltype(funcName##W)*{ return funcName##W; } }; #define DEC_STRFUNC(funcNameA,funcNameW) \ template<typename _T> \ struct funcNameA##T{}; \ template<> \ struct funcNameA##T<char> \ { static inline auto c()->decltype(funcNameA)*{ return funcNameA; } }; \ template<> \ struct funcNameA##T<wchar_t> \ { static inline auto c()->decltype(funcNameW)*{ return funcNameW; } }; #define DEC_STRFUNC_OVER(funcNameA,funcNameW) \ template<typename _T> \ struct funcNameA##T{}; \ template<> \ struct funcNameA##T<char> \ { static inline auto c()->funcNameA##_type{ return (funcNameA##_type)funcNameA; } }; \ template<> \ struct funcNameA##T<wchar_t> \ { static inline auto c()->funcNameW##_type{ return (funcNameW##_type)funcNameW; } }; #if(_MSC_VER>=1900) //vs2015 及 以上版本 能编译通过 #define DEC_STRFUNC_SIZE_ENABLE #define DEC_STRFUNC_SIZE(funcNameA,funcNameW) \ template<typename _T,size_t _Size> \ struct funcNameA##Ts{}; \ template<size_t _Size> \ struct funcNameA##Ts<char,_Size> \ { static inline auto c(){ return funcNameA<_Size>; } }; \ template<size_t _Size> \ struct funcNameA##Ts<wchar_t,_Size> \ { static inline auto c(){ return funcNameW<_Size>; } }; #endif #include "strFuncTypeDef.h"
commonMacro.h
/* * author: zyb * \brief common macro */ #pragma once #include <crtdefs.h> //////////////////////////////////////////////////////////////////////////// #define IS_EQUAL(lVal,rVal) ((lVal) == (rVal)) // equal #define NOT_EQUAL(lVal,rVal) ((lVal) != (rVal)) // not equal #define IS_TRUE(isTrue) IS_EQUAL(true , isTrue) // is true #define NOT_TRUE(notTrue) NOT_EQUAL(true , notTrue) // not true #define IS_INIT(isInit) IS_TRUE(isInit) // is init #define NOT_INIT(notInit) NOT_TRUE(notInit) // not init #define IS_FALSE(isFalse) IS_EQUAL(false , isFalse) // is false #define NOT_FALSE(notFalse) NOT_EQUAL(false , notFalse) // not false #define IS_ZERO(isZero) IS_EQUAL(0 , isZero) // is zero #define NOT_ZERO(notZero) NOT_EQUAL(0 , notZero) // not zero #define IS_EXIST(isExist) NOT_ZERO(isExist) //is exist #define NOT_EXIST(notExist) IS_ZERO(notExist) //not exist #define IS_NULLPTR(ptr) IS_EQUAL(nullptr , ptr) // is nullptr #define NOT_NULLPTR(ptr) NOT_EQUAL(nullptr , ptr) // not nullptr #define SAFDEL(ptr) if(NOT_NULLPTR(ptr)){delete ptr;ptr = nullptr;} //ptr not's array #define SAFDEL_A(ptr) if(NOT_NULLPTR(ptr)){delete[] ptr;ptr = nullptr;} //数组 //////////////////////////////////////////////////////////////////////////// /* * 便于调试! * 编写函数的时候 成功:返回 0 , 不成功:返回非零 */ #define RET_SUCCESS 0 #define IS_SUCCESS(ret) IS_EQUAL(RET_SUCCESS , ret) #define NOT_SUCCESS(ret) NOT_EQUAL(RET_SUCCESS, ret) #define IS_FAIL(ret) NOT_EQUAL(RET_SUCCESS, ret) #define NOT_FAIL(ret) IS_EQUAL(RET_SUCCESS, ret) ///////////////////////////////////////////////////// 内核句柄( from MSDN ) /* * SAFCLOSEHANDLE(handle) * VALIDHANDLE(handle) INVALIDHANDLE(handle) * handle 必须为以下函数返回的 HANDLE (非文件类内核句柄) * * CreateMutex, CreateMutexEx, OpenMutex * CreateProcess, OpenProcess, GetCurrentProcess * CreateThread, CreateRemoteThread, GetCurrentThread * CreateEvent, CreateEventEx, OpenEvent * CreateSemaphore, CreateSemaphoreEx, OpenSemaphore * CreateFileMapping, OpenFileMapping * CreateWaitableTimer, CreateWaitableTimerEx, OpenWaitableTimer * CreateMemoryResourceNotification, CreateJobObject, CreateIoCompletionPort * CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken, OpenThreadToken */ #define VALID_HANDLE(handle) NOT_NULLPTR(handle) // valid handle #define INVALID_HANDLE(handle) IS_NULLPTR(handle) // invalid handle #define SAFCLOSE_HANDLE(handle) if(VALID_HANDLE(handle)){CloseHandle(handle);handle = nullptr;} /* * SAFCLOSEHANDLE_F(handle) * VALIDHANDLE(handle) INVALIDHANDLE(handle) * handle 必须为以下函数返回的 HANDLE (文件类内核句柄) * * CreateFile, CreateMailslot * CreateNamedPipe, CreatePipe * CreateToolhelp32Snapshot */ #define VALID_HANDLE_F(handle) NOT_EQUAL(INVALID_HANDLE_VALUE , handle) // valid handle #define INVALID_HANDLE_F(handle) IS_EQUAL(INVALID_HANDLE_VALUE , handle) // invalid handle #define SAFCLOSE_HANDLE_F(handle) if(VALID_HANDLE_F(handle)){CloseHandle(handle);handle = INVALID_HANDLE_VALUE;} /* * socket, accept */ #define VALID_HSOCKET(hSocket) NOT_EQUAL(INVALID_SOCKET , hSocket) //valid socket handle #define INVALID_HSOCKET(hSocket) IS_EQUAL(INVALID_SOCKET , hSocket) //invalid socket handle #define SAFCLOSE_HSOCKET(hSocket) if(VALID_HSOCKET(hSocket)){closesocket(hSocket);hSocket = INVALID_SOCKET;} //////////////////////////////////////////////////////////////////////////// /* * __FILE__ __FUNC__ __LINE__(__STR_LINE__) __DATA__ __TIME__ * __FILEW__ __FUNCW__ __STR_LINEW__ __DATAW__ __TIMEW__ */ #define _TOSTRA(a) # a #define TOSTRA(a) _TOSTRA(a) // to ascii string #define _TOSTRW(a) L ## # a #define TOSTRW(a) _TOSTRW(a) // to unicode string #define _ATOW(str) L ## str #define ATOW(str) _ATOW(str) // ascii to unicode string #define __STR_LINE__ TOSTRA(__LINE__) #define __STR_LINEW__ TOSTRW(__LINE__) #ifndef __FILEW__ # define __FILEW__ ATOW(__FILE__) #endif #ifndef __FUNCTIONW__ # define __FUNCTIONW__ ATOW(__FUNCTION__) #endif #define __DATAW__ ATOW(__DATA__) #define __TIMEW__ ATOW(__TIME__) //////////////////////////////////////////////////////////////////////////// /* * 文件私有数据 */ #define FILE_PRIVATE_START namespace{ #define FILE_PRIVATE_END } /* * 库 */ #define LIB_START namespace LIB{ #define LIB_END } /* * 函数声明 */ #if _MSC_VER >= 1900 # define _CONST_EXPR constexpr # define _NO_EXCEPT noexcept #else # define _CONST_EXPR inline # define _NO_EXCEPT throw #endif //////////////////////////////////////////////////////////////////////////// /* * ASCII letter digit */ #define TO_LOWERCASE(letter) ((letter)|0x20) #define TO_UPPERCASE(letter) ((letter)&(~0x20)) #define IS_LOWERCASE(letter) ('a'<=(letter)&&(letter)<='z') #define IS_UPPERCASE(letter) ('A'<=(letter)&&(letter)<='Z') #define IS_LETTER(letter) (IS_LOWERCASE(letter)||IS_UPPERCASE(letter)) #define IS_DIGIT(digit) ('0'<=(digit)&&(digit)<='9') //////////////////////////////////////////////////////////////////////////// /* * message map : int/short/char..... */ #define BEGIN_INTMSG_MAP(msg) switch(msg){ #define MAP_INTMSG(msg,func) case msg: func; break; #define END_INTMSG_MAP() } #define END_INTMSG_MAPEX(func) default: func; break;} /* * message map : string/wstring... */ #define BEGIN_STRMSG_MAP(msg) \ do{ \ decltype(msg)& ref_strT = msg; #define MAP_STRMSG(msg,func) \ if (ref_strT == msg) \ { \ func; \ break; \ } #define END_STRMSG_MAP() \ } while (0); #define END_STRMSG_MAPEX(func) \ func; \ } while (0); //////////////////////////////////////////////////////////////////////////// /* * LIB_ASSERT */ #include <assert.h> #define LIB_ASSERT(a) assert(a) //////////////////////////////////////////////////////////////////////////// /* * use in template */ #include "makeFuncMacro.h" /////////////////////////////////////////////////////////////////////////// #include <wtypes.h>
使用例子:
Helper.hpp
/* * author: zyb * \brief helper */ #pragma once #include <string> #include <stdlib.h> #include "commonMacro.h" LIB_START #define _CRT_SECURE_NO_WARNINGS #pragma warning(push) #pragma warning(disable:4996) // 获得模块虚拟地址 PVOID GetModuleBase(PVOID pAddr = nullptr) { MEMORY_BASIC_INFORMATION mbi = { 0 }; if (IS_NULLPTR(pAddr)) pAddr = static_cast<PVOID>(GetModuleBase); VirtualQueryEx(GetCurrentProcess(), pAddr, &mbi, sizeof(mbi)); return mbi.AllocationBase; } template<typename _charT> struct strT { typedef std::string type; }; template<> struct strT<wchar_t> { typedef std::wstring type; }; #define RET_STR(_charT) typename strT<_charT>::type DEC_CFUNC1(splitpath) DEC_SYSFUNC(GetModuleFileName) // 获得程序文件目录 template<typename _charT> RET_STR(_charT) GetProgramDirT() { _charT pProgramPath[MAX_PATH]; _charT pDrive[_MAX_DRIVE]; _charT pProgramDir[_MAX_DIR]; RET_STR(_charT) strRetDir; DWORD dwRet = GetModuleFileNameT<_charT>::c() (nullptr, pProgramPath, MAX_PATH); if (IS_ZERO(dwRet)) return strRetDir; splitpathT<_charT>::c()(pProgramPath, pDrive, pProgramDir, nullptr, nullptr); strRetDir = pDrive; strRetDir += pProgramDir; return strRetDir; } //获得模块文件目录 template<typename _charT> RET_STR(_charT) GetModuleDirT(PVOID pAddr = nullptr) { _charT pModulePath[MAX_PATH]; _charT pDrive[_MAX_DRIVE]; _charT pModuleDir[_MAX_DIR]; RET_STR(_charT) strRetDir; PVOID pModuleAddr = GetModuleBase(pAddr); DWORD dwRet = GetModuleFileNameT<_charT>::c() ((HMODULE)pModuleAddr, pModulePath, MAX_PATH); if (IS_ZERO(dwRet)) return strRetDir; splitpathT<_charT>::c()(pModulePath, pDrive, pModuleDir, nullptr, nullptr); strRetDir = pDrive; strRetDir += pModuleDir; return strRetDir; } // 获得程序文件名 template<typename _charT> RET_STR(_charT) GetProgramNameT() { _charT pProgramPath[MAX_PATH]; _charT pProgramName[_MAX_FNAME]; RET_STR(_charT) strRetFName; DWORD dwRet = GetModuleFileNameT<_charT>::c() (nullptr, pProgramPath, MAX_PATH); if (IS_ZERO(dwRet)) return strRetFName; splitpathT<_charT>::c()(pProgramPath, nullptr, nullptr, pProgramName, nullptr); return pProgramName; } // 获得模块文件名 template<typename _charT> RET_STR(_charT) GetModuleNameT(PVOID pAddr = nullptr) { _charT pModulePath[MAX_PATH]; _charT pModuleName[_MAX_FNAME]; RET_STR(_charT) strRetFName; PVOID pModuleAddr = GetModuleBase(pAddr); DWORD dwRet = GetModuleFileNameT<_charT>::c() ((HMODULE)pModuleAddr, pModulePath, MAX_PATH); if (IS_ZERO(dwRet)) return strRetFName; splitpathT<_charT>::c()(pModulePath, nullptr, nullptr, pModuleName, nullptr); return pModuleName; } // 获得程序文件后缀 template<typename _charT> RET_STR(_charT) GetProgramPostfixT() { _charT pProgramPath[MAX_PATH]; _charT pProgramPostfix[_MAX_FNAME]; RET_STR(_charT) strRetPostfix; DWORD dwRet = GetModuleFileNameT<_charT>::c() (nullptr, pProgramPath, MAX_PATH); if (IS_ZERO(dwRet)) return strRetPostfix; splitpathT<_charT>::c()(pProgramPath, nullptr, nullptr, nullptr, pProgramPostfix); return pProgramPostfix; } // 获得模块文件后缀 template<typename _charT> RET_STR(_charT) GetModulePostfixT(PVOID pAddr = nullptr) { _charT pModulePath[MAX_PATH]; _charT pModulePostfix[_MAX_FNAME]; RET_STR(_charT) strRetPostfix; PVOID pModuleAddr = GetModuleBase(pAddr); DWORD dwRet = GetModuleFileNameT<_charT>::c() ((HMODULE)pModuleAddr, pModulePath, MAX_PATH); if (IS_ZERO(dwRet)) return strRetPostfix; splitpathT<_charT>::c()(pModulePath, nullptr, nullptr, nullptr, pModulePostfix); return pModulePostfix; } #ifdef UNICODE # define GetProgramDir GetProgramDirT<wchar_t> # define GetModuleDir GetModuleDirT<wchar_t> # define GetProgramName GetProgramNameT<wchar_t> # define GetModuleName GetModuleNameT<wchar_t> # define GetProgramPostfix GetProgramPostfixT<wchar_t> # define GetModulePostfix GetModulePostfixT<wchar_t> #else # define GetProgramDir GetProgramDirT<char> # define GetModuleDir GetModuleDirT<char> # define GetProgramName GetProgramNameT<char> # define GetModuleName GetModuleNameT<char> # define GetProgramPostfix GetProgramPostfixT<char> # define GetModulePostfix GetModulePostfixT<char> #endif #undef _CRT_SECURE_NO_WARNINGS #pragma warning(pop) LIB_END
test.cpp
#include "Helper.hpp" using namespace LIB; void main() { std::string ModuleDir; std::string ProgramDir; std::string ModuleName; std::string ProgramName; std::string ModulePostfix; std::string ProgramPostfix; ModuleDir = GetModuleDirT<char>(); ProgramDir = GetProgramDirT<char>(); ModuleName = GetModuleNameT<char>(); ProgramName = GetProgramNameT<char>(); ModulePostfix = GetModulePostfixT<char>(); ProgramPostfix = GetProgramPostfixT<char>(); while (true); }
模板,宏,让你更加的了解编译器。好好体会吧。