不多说了,看代码吧,我们不需要写两套关于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);
}
模板,宏,让你更加的了解编译器。好好体会吧。