多一分钟学习,早一秒钟提高

VC++、C++、Socket、DirectUI、wxWidgets、Cocos2d-x、CocosCreator、Unity3D、UE4、ThinkPHP
posts - 32, comments - 12, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

网络游戏常用类

Posted on 2014-05-27 21:38 虚空骄阳 阅读(511) 评论(0)  编辑 收藏 引用 所属分类: C++
1、通用单例类
 1 #ifndef _SINGLETON_H
 2 #define _SINGLETON_H
 3 
 4 namespace GameGeneric
 5 {
 6     template<class T>
 7     class Singleton
 8     {
 9     public:
10         static T* instance()
11         {
12             if ( !_instance )
13             {
14                 _instance = new T;
15             }
16             return _instance;
17         }
18 
19     protected:
20         // 使用保护构造是为了让用户不能在栈上声明一个实例
21         Singleton() {}
22 
23     private:
24         static T* _instance;        // 实例静态指针
25     };
26 
27     // 静态实例指针初始化
28     template <class T> T* Singleton<T>::_instance = NULL;
29 
30 }
31 
32 #endif

//使用的时候只需要单件类继承此模板即可。   
class Test : public Singleton<Test >{...};

2、
Dll(so)动态加载
 1 #ifndef __LIB_DEF_H_
 2 #define __LIB_DEF_H_
 3 
 4 namespace GameGeneric  
 5 {  
 6     // DLL对象创建辅助类   
 7     template<const TCHAR*& szFileName>  
 8     class DllApi
 9     {
10     public:
11         static BOOL Load()
12         {
13             if( !m_h )
14             {
15                 m_h = ::LoadLibrary(szFileName);
16             }
17             return m_h != NULL;
18         }
19         static void Unload()
20         {
21             if( m_h )
22             {
23                 ::FreeLibrary(m_h);
24             }
25             m_h = NULL;
26         }  
27     protected:  
28         static HMODULE m_h;  
29     };    
30     template<const TCHAR*& szFileName> HMODULE DllApi<szFileName>::m_h;  
31   
32     //库文件前后缀   
33 #ifdef WIN32   
34     #define __DLL_PREFIX    _T("")   
35     #define __DLL_SUFFIX    _T(".dll")   
36 #else   
37     #define __DLL_PREFIX    _T("lib")   
38     #define __DLL_SUFFIX    _T(".so")   
39 #endif   
40   
41     // 声明DLL文件名常量   
42 #define DECLARE_DLL_FILE(module) extern "C" const TCHAR* module;   
43   
44     // 定义DLL文件名常量   
45 #if !defined(_LIB) && !defined(_USE_STATIC_LIB)   
46     #define DEFINE_DLL_FILE(module) extern "C" const TCHAR* module = _T("./")""__DLL_PREFIX""_T(#module)""__DLL_SUFFIX;   
47 #else   
48     #define DEFINE_DLL_FILE(module)   
49 #endif   
50 }  
51   
52 #endif

本例中使用了LoadLibrary,是windows的实现方法,在后面平台相关处理中,将linux的函数封装,和windows同名。
此模板使用方法很简单:
 1 #if defined(_LIB) || defined(_USE_STATIC_LIB)    // 静态库版本
 2     #ifndef _LUA_ENGINE_API
 3         #define _LUA_ENGINE_API IMPORT_API
 4         #pragma comment(lib,  MAKE_LIB_NAME(LuaEngine))
 5     #endif
 6 
 7     _LUA_ENGINE_API ILuaEngine* GlobalLuaEngine();
 8 #else
 9     DECLARE_DLL_FILE(LuaEngine);
10     class GlobalLuaEngine : public DllApi<LuaEngine>
11     {
12     typedef ILuaEngine* (*CREATE_PROC)();
13     ILuaEngine* m_p;
14     public:
15         GlobalLuaEngine() : m_p(NULL)
16         {
17             Load();
18             static CREATE_PROC func;
19             if(func == NULL) func = (CREATE_PROC)::GetProcAddress(m_h, "GlobalLuaEngine");
20             if(func != NULL) m_p = func();
21         }
22         operator ILuaEngine* (){ return m_p; }
23         ILuaEngine* operator ->(){ return m_p; }
24     };
25 #endif

上面代码所示,LuaEngine是一个dll,我们在加载它的时候,使用了一个额外的类,在他的构造函数里面加载了共享库。而且在应用级上也与平台无关。

3、
跨平台的若干处理
Windows的处理相当简单,只是定义一些简单的宏:
 1 // gwindef.h : windows开发定义文件   
 2 #ifndef __G_WIN_DEF_H_   
 3 #define __G_WIN_DEF_H_   
 4   
 5 #include <windows.h>   
 6 #include <process.h>   
 7 #include <tchar.h>   
 8 #include <unknwn.h>   
 9 #include <stdio.h>   
10 #include <stdlib.h>   
11   
12 #define SYS_API         WINAPI   
13 #define STD_CALL        __stdcall   
14 #if !defined(_LIB)   
15 #define EXPORT_API      extern "C" _declspec(dllexport)   
16 #else   
17 #define EXPORT_API      extern "C"   
18 #endif   
19 #if !defined(_LIB) && !defined(_USE_STATIC_LIB)   
20 #define IMPORT_API      extern "C" _declspec(dllimport)   
21 #else   
22 #define IMPORT_API      extern "C"   
23 #endif   
24   
25 #endif // ndef __G_WIN_DEF_H_

为了开发的时候去除平台无关性,在Linux的开发中,我们需要做一些包装,使其在开发过程中和window代码一致,如下:
  1 // glindef.h : linux开发定义文件
  2 #ifndef __G_LIN_DEF_H_
  3 #define __G_LIN_DEF_H_
  4 // 
  5 #include <stdlib.h>
  6 #include <stdio.h>
  7 #include <string.h>
  8 #include <wchar.h>
  9 #include <unistd.h>
 10 #include <pthread.h>
 11 #include <semaphore.h>
 12 #include <errno.h>
 13 #include <sys/times.h>
 14 #include <time.h>
 15 #include <dlfcn.h>
 16 #include <sys/types.h>
 17 #include <linux/unistd.h>
 18 
 19 inline _syscall0(pid_t, gettid)        /* Using syscall(2) may be preferable; see intro(2) */
 20 
 21 #ifdef UNICODE
 22 #define _T(str)        L##str
 23 #else
 24 #define _T(str)        str
 25 #endif
 26 
 27 #define TRUE        1
 28 #define FALSE        0
 29 
 30 #define MAX_PATH        256
 31 
 32 #define SYS_API
 33 #define STD_CALL
 34 #define EXPORT_API        extern "C"
 35 #define IMPORT_API        extern "C"
 36 
 37 /// HRESULT 常量定义
 38 typedef long        HRESULT;
 39 enum HResult
 40 {
 41     S_OK = ((HRESULT)0x00000000),            /**< 成功,值为0 */
 42     S_FALSE = ((HRESULT)0x00000001),            /**< 成功,但值为1 */
 43     E_FAIL = _HRESULT_TYPEDEF_(0x80004005),        /**< 未定义错误 */
 44     E_NOTIMPL = _HRESULT_TYPEDEF_(0x80004001),        /**< 接口未实现 */
 45     E_OUTOFMEMORY = _HRESULT_TYPEDEF_(0x8007000E),    /**< 内存不足 */
 46     E_INVALIDARG = _HRESULT_TYPEDEF_(0x80070057),        /**< 无效参数 */
 47     E_NOINTERFACE = _HRESULT_TYPEDEF_(0x80004002),    /**< 接口不存在 */
 48     E_POINTER = _HRESULT_TYPEDEF_(0x80004003),        /**< 无效指针 */
 49     E_HANDLE = _HRESULT_TYPEDEF_(0x80070006),        /**< 无效句柄 */
 50     E_ABORT = _HRESULT_TYPEDEF_(0x80004004),        /**< 操作被取消 */
 51     E_ACCESSDENIED = _HRESULT_TYPEDEF_(0x80070005),    /**< 访问拒绝 */
 52     E_PENDING = _HRESULT_TYPEDEF_(0x8000000A),        /**< 操作被挂起 */
 53     E_UNEXPECTED = _HRESULT_TYPEDEF_(0x8000FFFF)        /**< 未预料的错误 */
 54 };
 55 
 56 /// 判定 HRESULT 值是否为成功值
 57 #define SUCCEEDED(Status)    ((HRESULT)(Status) >= 0)
 58 /// 判定 HRESULT 值是否为失败值
 59 #define FAILED(Status)        ((HRESULT)(Status) < 0)
 60 
 61 /// GUID 类型定义
 62 /**
 63 要定义 GUID 常量请使用 GUID 专门的生成工具(比如 VS 携带的 guidgen.exe 程序)来生成,
 64 以确保其唯一性。
 65 接口 ID(IID), 类 ID(CLSID)均为 GUID 的别名*/
 66 struct GUID
 67 {
 68     unsigned long  Data1;
 69     unsigned short Data2;
 70     unsigned short Data3;
 71     unsigned char  Data4[8];
 72 };
 73 
 74 typedef GUID IID;
 75 typedef GUID CLSID;
 76 #define REFGUID const GUID&
 77 #define REFIID const IID&
 78 #define REFCLSID const CLSID&
 79 
 80 /// 判断两个 GUID 是否相等(内联版)
 81 inline BOOL InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2)
 82 {
 83     return ((long*)&rguid1)[0] == ((long*)&rguid2)[0] && 
 84         ((long*)&rguid1)[1] == ((long*)&rguid2)[1] &&
 85         ((long*)&rguid1)[2] == ((long*)&rguid2)[2] &&
 86         ((long*)&rguid1)[3] == ((long*)&rguid2)[3];
 87 }
 88 
 89 /// 判断两个 GUID 是否相等
 90 inline BOOL IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
 91 {
 92     return !memcmp(&rguid1, &rguid2, sizeof(GUID));
 93 }
 94 
 95 #define CopyMemory(dest, src, len)        memcpy((dest), (src),(len))
 96 #define ZeroMemory(dest, len)        memset((dest), 0, (len))
 97 #define FillMemory(dest, len, value)        memset((dest), value, (len))
 98 #define GetCurrentThreadId            gettid
 99 #define OutputDebugString(str)        tprintf(_T("%s"), str)
100 #define LoadLibrary(file)            dlopen(file, RTLD_NOW)
101 #define FreeLibrary            dlclose
102 #define GetProcAddress            dlsym
103 
104 inline int GetLastError()
105 {
106     return errno;
107 }
108 
109 inline DWORD GetTickCount()
110 {
111     static int clkTck = 0;
112     if(clkTck == 0) clkTck = 1000 / ::sysconf(_SC_CLK_TCK);
113     return (DWORD)::times(NULL) * clkTck;    // 不能溢出
114 }
115 
116 inline void Sleep(DWORD ms)
117 {
118     struct timespec req, rem;
119     req.tv_sec = ms / 1000; req.tv_nsec = (ms % 1000) * 1000000;
120     while(::nanosleep(&req, &rem) && ::GetLastError() == EINTR) req = rem;
121 }
122 
123 inline long InterlockedIncrement(long volatile* v)
124 {
125     long src = 1;
126     /* Modern 486+ processor */
127     __asm__ __volatile__(
128         "lock xaddl %0, %1;"
129         :"=r"(src), "=m"(*v)
130         :"0"(src));
131     return src + 1;
132 }
133 
134 inline long InterlockedDecrement(long volatile* v)
135 {
136     long src = -1;
137     /* Modern 486+ processor */
138     __asm__ __volatile__(
139         "lock xaddl %0, %1;"
140         :"=r"(src), "=m"(*v)
141         :"0"(src));
142     return src - 1;
143 }
144 
145 #define stricmp                        strcasecmp
146 
147 #include <ctype.h>
148 inline void strupr(char *s)
149 {
150     while (*s)
151         {
152             *s = toupper((unsigned char) *s);
153             s++;
154     }
155 }
156 
157 inline void strlwr(char *s)
158 {
159     while (*s)
160         {
161         *s = tolower((unsigned char) *s);
162         s++;
163     }
164 }
165 
166 #endif // ndef __G_LIN_DEF_H_

功能是对一些常用函数改装成Windows相关函数的名字

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理