• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            戰魂小筑

            討論群:309800774 知乎關注:http://zhihu.com/people/sunicdavy 開源項目:https://github.com/davyxu

               :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              257 隨筆 :: 0 文章 :: 506 評論 :: 0 Trackbacks

            #

            CodeLite極力的模仿Visual Studio的界面及表現形式. 但是在有些配置項上卻存在著操作不同, 看圖說話:

            image

            這是項目中的工程配置設定項中的調試器參數設置. 圖中將Program啟動程序項設定為相對路徑, 而Working Folder工作目錄項設為絕對路徑.

            這樣的設定無法啟動調試器, gdb將報錯, 無法找到調試程序:

            image

            研究了一下, 發現設定項里引導你使用瀏覽目錄對話框進行選擇, 嘗試一下, 將Program改為絕對路徑

            image

            F5開始調試, 不報錯, main中使用getcwd獲取當前路徑驗證, 設置正確, 問題解決

             

            分析: CodeLite應該只是將兩個參數簡單的傳給了gdb, 但是gdb并不知道工程相對路徑,因此報錯. 這對于CodeLite開發者來說,理解是正確的, 程序員思想.

            但是對于產品來說是失敗的

            VisualStudio的調試器與IDE結合緊密, 因此以產品思想開發程序, 就能避免這種類似的問題

            posted @ 2012-03-30 16:07 戰魂小筑 閱讀(5131) | 評論 (0)編輯 收藏

            在lua中, #操作符用于獲取對象大小, 對于table來說, 獲取的是table元素個數, 對于字符串來說獲取的是字符串長度

            另外一種獲取方法是table.getn(obj), 但是這個方法已經標記為廢除了, 盡量使用通用且簡潔的#操作符

             

            使用lua api實現此功能就需要用到lua_objlen( ),但是這個功能未在luabind中提供.所以我們順手添加一個

            首先找到luabind源碼的object.hpp中取對象類型的type函數,在其下添加以下代碼

             

              1: template<class ValueWrapper>
              2: inline int obj_size(ValueWrapper const& value)
              3: {
              4:     lua_State* interpreter = value_wrapper_traits<ValueWrapper>::interpreter(
              5:         value
              6:         );
              7: 
              8:     value_wrapper_traits<ValueWrapper>::unwrap(interpreter, value);
              9:     detail::stack_pop pop(interpreter, 1);
             10:     return lua_objlen(interpreter, -1);
             11: }

             

            重新編譯你的代碼, 就可以這樣使用luabind::obj_size( obj ) 獲取對象大小了
            posted @ 2012-03-27 17:36 戰魂小筑 閱讀(1871) | 評論 (0)編輯 收藏

            以下代碼使用luabind進行lua的coroutine測試

               1: void ScriptManagedChannel::OnServiceInitialize()
               2: {    
               3:     try
               4:     {        
               5:         mThread = lua_newthread( GScriptScriptContext->GetVM() );
               6:  
               7:         luabind::resume_function<void>( mThread, "ScriptMain", this );
               8:  
               9:         Resume();
              10:     }
              11:     catch (std::exception& e)
              12:     {
              13:         const char* ErrorMsg = lua_tostring( GScriptScriptContext->GetVM(), -1 );            
              14:         printf("%s\n", e.what() );
              15:     }
              16:  
              17:     
              18: }
              19:  
              20: void ScriptManagedChannel::Resume( )
              21: {
              22:     luabind::resume<void>( mThread );
              23: }
              24:  
              25: void ScriptManagedChannel::StopTest( )
              26: {
              27:     lua_yield( mThread, 0 );
              28: }
              29:  
              30:  

            代碼中, mThread類型為lua_State*類型

            GScriptScriptContext->GetVM()是加載了代碼的lua_State*

            StopTest為注冊為ScriptManagedChannel類成員函數到lua中的定義

            接下來看lua端的測試代碼:

               1: function ScriptMain( Channel )
               2:  
               3:     
               4:     for i = 1, 5 do
               5:     
               6:     print("done", i)
               7:     
               8:     Channel:StopTest( )
               9:     
              10:     
              11:     
              12:     end
              13: end

            剛開始,在測試代碼時, lua中有個手誤而造成的錯誤, 導致C++代碼運行到第7行時彈出assert

            位于:luabind-0.9.1\luabind\detail\call_function.hpp 第264行,對應以下代碼第13行

               1: ~proxy_function_void_caller()
               2: {
               3:     if (m_called) return;
               4:  
               5:     m_called = true;
               6:     lua_State* L = m_state;
               7:  
               8:     int top = lua_gettop(L);
               9:  
              10:     push_args_from_tuple<1>::apply(L, m_args);
              11:     if (m_fun(L, boost::tuples::length<Tuple>::value, 0))
              12:     {
              13:         assert(lua_gettop(L) == top - m_params + 1);
              14:  
              15: NO_EXCEPTIONS
              16:         throw luabind::error(L);
              17: #else
              18:         error_callback_fun e = get_error_callback();
              19:         if (e) e(L);
              20:     
              21:         assert(0 && "the lua function threw an error and exceptions are disabled."
              22:                 " If you want to handle the error you can use luabind::set_error_callback()");
              23:         std::terminate();
              24: #endif
              25:     }
              26:     // pops the return values from the function call
              27:     stack_pop pop(L, lua_gettop(L) - top + m_params);
              28: }

            11行代碼中調用的是lua_resume, 返回的是運行錯誤, 但是被13行的assert擋住了, 無法通過第16行拋出異常被外面捕獲.

            因此,嘗試注釋第13行, 再測試, 可以在lua拋出錯誤后, 在棧頂捕獲到coroutine函數resume時報出的錯誤信息.問題解決

             

            對于lua的coroutine, 網上資料不多, 這里有一篇比較詳細的代碼

            我比較疑惑的是, 有沒有必要將代碼在dofile或者dobuffer時, 必須傳入newthread出的state? 如果還是傳入原始的state會有什么影響?

            歡迎各位有此經驗的討論

            posted @ 2012-03-27 10:38 戰魂小筑 閱讀(1527) | 評論 (2)編輯 收藏

            我們有時需要限制lua代碼的運行環境,或者是讓使用者不能訪問到lua的一些全局函數.lua語言本身沒有類似于C++, C#, Java那樣的成員訪問控制. 但lua提供了setfenv函數可以很靈活的處理各類權限問題

            廢話不多說, 看代碼

               1:  -- 創建沙盒
               2:  function SpawnSandBox( )
               3:   
               4:      local SandBoxGlobals = {}
               5:      
               6:      -- 基礎函數添加
               7:      SandBoxGlobals.print             = print
               8:      SandBoxGlobals.table             = table
               9:      SandBoxGlobals.string             = string     
              10:      SandBoxGlobals.math               = math 
              11:      SandBoxGlobals.assert             = assert 
              12:      SandBoxGlobals.getmetatable    = getmetatable 
              13:      SandBoxGlobals.ipairs             = ipairs 
              14:      SandBoxGlobals.pairs             = pairs 
              15:      SandBoxGlobals.pcall             = pcall 
              16:      SandBoxGlobals.setmetatable    = setmetatable 
              17:      SandBoxGlobals.tostring        = tostring 
              18:      SandBoxGlobals.tonumber        = tonumber 
              19:      SandBoxGlobals.type            = type 
              20:      SandBoxGlobals.unpack             = unpack 
              21:      SandBoxGlobals.collectgarbage     = collectgarbage
              22:      SandBoxGlobals._G                = SandBoxGlobals
              23:      
              24:      return SandBoxGlobals
              25:  end
              26:   
              27:  -- 在沙盒內執行腳本, 出錯時返回錯誤, nil表示正確
              28:  function ExecuteInSandBox( SandBox, Script )
              29:      
              30:      local ScriptFunc, CompileError = loadstring( Script )
              31:      
              32:      if CompileError then
              33:          return CompileError
              34:      end
              35:      
              36:      setfenv( ScriptFunc, SandBox )
              37:      
              38:      local Result, RuntimeError = pcall( ScriptFunc )
              39:      if RuntimeError then
              40:          return RuntimeError
              41:      end
              42:      
              43:      return nil
              44:  end
              45:   
              46:  function ProtectedFunction( )
              47:      print("protected func")
              48:  end
              49:   
              50:   
              51:  local SandBox = SpawnSandBox( )
              52:   
              53:   
              54:  print ( "Response=", ExecuteInSandBox( SandBox, "table.foreach( _G, print )" ) )
              55:   
              56:  print ( "Response=", ExecuteInSandBox( SandBox, "ProtectedFunction()" ) )
              57:   
              58:  SandBox.ProtectedFunction = ProtectedFunction
              59:   
              60:  print ( "Response=", ExecuteInSandBox( SandBox, "ProtectedFunction()" ) )

             

            54行執行結果是

             

               1:  _G    table: 00421258
               2:  string    table: 00421050
               3:  pairs    function: 00567F58
               4:  collectgarbage    function: 005675F0
               5:  unpack    function: 004217E8
               6:  assert    function: 005675B0
               7:  print    function: 00567830
               8:  ipairs    function: 00567F28
               9:  type    function: 004217A8
              10:  tonumber    function: 00421768
              11:  tostring    function: 00421788
              12:  table    table: 00420DA8
              13:  math    table: 004210C8
              14:  setmetatable    function: 00421748
              15:  getmetatable    function: 00567710
              16:  pcall    function: 005677F0
              17:  Response=    nil
             
            54行由于沒有注冊這個全局函數, 因此無法訪問
            Response=    [string "ProtectedFunction()"]:1: attempt to call global 'ProtectedFunction' (a nil value)
             
            58行在全局環境中加上了這個函數,因此在60行訪問正常
            protected func
            Response=    nil
             
            posted @ 2012-03-02 09:40 戰魂小筑 閱讀(4206) | 評論 (0)編輯 收藏

            Linux下的ldd命令可以查看一個可執行文件/共享庫/靜態庫的依賴, 但是想得到這些依賴文件, 必須手動去找,非常麻煩

            這里是一個Shell可以將依賴列表中的文件拷貝到指定目錄

            deplist=$( ldd $1 | awk '{if (match($3,"/")){ print $3}}' )
            cp $deplist $2
            代碼解釋: ldd導出列表, 這個列表打印出來很丑

            linux-gate.so.1 =>  (0x00ed2000)
                liblog4cpp.so.4 => /usr/local/lib/liblog4cpp.so.4 (0x00657000)
                libprotobuf.so.7 => /usr/local/lib/libprotobuf.so.7 (0x00360000)
                libboost_filesystem.so.1.48.0 => /usr/local/lib/libboost_filesystem.so.1.48.0 (0x00a9a000)
                libboost_program_options.so.1.48.0 => /usr/local/lib/libboost_program_options.so.1.48.0 (0x00110000)
                libboost_system.so.1.48.0 => /usr/local/lib/libboost_system.so.1.48.0 (0x00a85000)
                libboost_thread.so.1.48.0 => /usr/local/lib/libboost_thread.so.1.48.0 (0x00179000)
                libunwind-x86.so.7 => /usr/lib/libunwind-x86.so.7 (0x00821000)
                libluabindd.so.0.9.0 => /usr/local/lib/libluabindd.so.0.9.0 (0x00bb3000)
                libmysqlpp.so.3 => /usr/local/lib/libmysqlpp.so.3 (0x00de5000)
                libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0x001a9000)
                libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0x00782000)
                libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0x00aea000)
                libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00447000)
                libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0x00abd000)
                librt.so.1 => /lib/i386-linux-gnu/librt.so.1 (0x00193000)
                libnsl.so.1 => /lib/i386-linux-gnu/libnsl.so.1 (0x00294000)
                libunwind.so.7 => /usr/lib/libunwind.so.7 (0x002ab000)
                libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0x00e8a000)
                libmysqlclient_r.so.16 => /usr/lib/libmysqlclient_r.so.16 (0x0083b000)
                /lib/ld-linux.so.2 (0x00608000)
                libz.so.1 => /lib/i386-linux-gnu/libz.so.1 (0x002c0000)

             

            我們發現第一行的so沒有對應的庫地址, 因此我們使用awk的腳本功能,判斷第三個參數,也就是=>之后的路徑必須包含/

            之后將第一行的輸出重定向到變量中, 再使用cp指令從列表拷貝到指定目錄

            posted @ 2012-02-29 16:05 戰魂小筑 閱讀(3060) | 評論 (0)編輯 收藏

            1.1 為進程添加守護進程

            參考鏈接http://yubosun.akcms.com/tech/linux-daemon-program.htm

               1:  #include <unistd.h> 
               2:  #include <signal.h> 
               3:  #include <sys/types.h> 
               4:  #include <sys/stat.h> 
               5:  #include <stdio.h> 
               6:  #include <stdlib.h>
               7:   
               8:  #ifndef NOFILE 
               9:  #define NOFILE 3 
              10:  #endif
              11:   
              12:  void init_daemon() 
              13:  { 
              14:          int pid; 
              15:          int i; 
              16:          if(pid = fork()) exit(0); //父進程,退出 
              17:   
              18:          else if(pid < 0) exit(1); //fork失敗 
              19:   
              20:          /* 子進程繼續執行 */ 
              21:          setsid(); //創建新的會話組,子進程成為組長,并與控制終端分離 
              22:   
              23:          /* 防止子進程(組長)獲取控制終端 */ 
              24:          if(pid = fork()) exit(0); //父進程,退出 
              25:   
              26:          else if(pid < 0) exit(1); //fork錯誤,退出 
              27:   
              28:          /* 第二子進程繼續執行 , 第二子進程不再是會會話組組長*/ 
              29:   
              30:          //for(i = 0; i < NOFILE; i++) /* 關閉打開的文件描述符*/ 
              31:          //{ 
              32:          //close(i); 
              33:          //} 
              34:          chdir("/tmp"); /* 切換工作目錄 */ 
              35:          umask(0); /* 重設文件創建掩碼 */ 
              36:          return; 
              37:  }
              38:   
              39:  int main(int argc, char* argv[])
              40:  {    
              41:      FILE *fp; 
              42:   
              43:      signal(SIGCHLD, SIG_IGN); /* 忽略子進程結束信號,防止出現僵尸進程 */ 
              44:   
              45:      init_daemon(); 
              46:   
              47:      while(1) 
              48:      { 
              49:              sleep(1);
              50:              
              51:  // 注意, 日志寫到這個目錄
              52:              if((fp = fopen("/var/tmp/test.log", "a")) != NULL) 
              53:              { 
              54:                      fprintf(fp, "%s\n", "test message"); 
              55:                      fclose(fp); 
              56:              } 
              57:      } 
              58:   
              59:      return 0;
              60:  }

            1.2 編寫服務腳本

            參考鏈接http://blog.sina.com.cn/s/blog_57421ff80100c7nn.html

            紅色字是需要填寫的部分, 文件頭部分可以選填

               1:  #!/bin/bash
               2:   
               3:  # chkconfig: 3 3 1
               4:   
               5:  # description: web kill center
               6:   
               7:  EXEC_PATH=/usr/local/bin
               8:   
               9:  EXEC=CenterServiced
              10:   
              11:  PID_FILE=/var/run/CenterServiced.pid
              12:   
              13:  DAEMON=/usr/local/bin/CenterServiced
              14:   
              15:  if ! [ -x $EXEC_PATH/$EXEC ] ; then
              16:   
              17:  echo "ERROR: $EXEC_PATH/$EXEC not found"
              18:   
              19:  exit 1
              20:   
              21:  fi
              22:   
              23:  stop()
              24:   
              25:  {
              26:   
              27:  echo "Stoping $EXEC ..."
              28:   
              29:  killall $DAEMON >/dev/null
              30:   
              31:  echo "Shutting down $EXEC: [ OK ]"
              32:   
              33:  }
              34:   
              35:  start()
              36:   
              37:  {
              38:   
              39:  echo "Starting $EXEC ..."
              40:   
              41:  $DAEMON > /dev/null &
              42:   
              43:  echo "Starting $EXEC: [ OK ]"
              44:   
              45:  }
              46:   
              47:  restart()
              48:   
              49:  {
              50:   
              51:  stop
              52:   
              53:  start
              54:   
              55:  }
              56:   
              57:  case "$1" in
              58:   
              59:  start)
              60:   
              61:  start
              62:   
              63:  ;;
              64:   
              65:  stop)
              66:   
              67:  stop
              68:   
              69:  ;;
              70:   
              71:  restart)
              72:   
              73:  restart
              74:   
              75:  ;;
              76:   
              77:  status)
              78:   
              79:  status -p $PID_FILE $DAEMON
              80:   
              81:  ;;
              82:   
              83:  *)
              84:   
              85:  echo "Usage: service $EXEC {start|stop|restart|status}"
              86:   
              87:  exit 1
              88:   
              89:  esac
              90:   
              91:  exit $?
              92:   

            1.3 創建服務

            參考鏈接http://hi.baidu.com/guanxiansun/blog/item/b4c7dcf55f6011e47709d724.html

            將服務文件拷貝到/etc/init.d下,去掉擴展名, 文件名即是服務名

            chmod +x ./wkcenter

            如果不設置啟動, 那么service中將無法找到該服務及操作

            1.4 設置啟動順序

            創建啟動鏈接

            ln /etc/init.d/wkcenter /etc/rc3.d/S03wkcenter

            創建關閉鏈接

            ln /etc/init.d/wkcenter /etc/rc0.d/K03wkcenter

            1.5 添加服務

            chkconfig --add wkcenter

            查看服務是否存在

            chkconfig –-list | grep wkcenter

            查看服務狀態

            chkconfig wkcenter on

            注意, 確認wkcenter在2,3,4,5中任意或者部分開啟, 必須為綠字. 灰字代表服務無法開機啟動或者其他問題

            1.6 測試

            臨時開啟命令測試

            service wkcenter start

            1.7 QA

            參考鏈接: http://blog.526net.com/?p=1706

            1. 服務切記不可放在用戶home目錄, 最好放在/usr/local/bin目錄, 日志寫到var中, 否則服務測試正常,但是無法自動啟動

            2. Linux下, 父進程啟動的程序的生命期跟隨父進程, 父進程可以是終端, 父進程一旦終止, 子進程都必須結束. 因此守護進程需要脫離父進程,避免被父進程生命期控制

            posted @ 2012-02-28 10:52 戰魂小筑 閱讀(7305) | 評論 (4)編輯 收藏

            參考來源:http://blog.csdn.net/flying8127/article/details/1598521

            在原來原基礎上,將代碼整理,并加強安全性. 并按照WindowsAPI設計, 添加輸出緩沖長度探測功能

            當OutUTFString為NULL時, 可以進行輸出的UTF8字符串長度探測

               1:  uint32 UniCharToUTF8(wchar_t UniChar, char *OutUTFString)
               2:      {
               3:   
               4:          uint32 UTF8CharLength = 0;
               5:   
               6:          if (UniChar < 0x80)
               7:          {  
               8:              if ( OutUTFString )
               9:                  OutUTFString[UTF8CharLength++] = (char)UniChar;
              10:              else
              11:                  UTF8CharLength++;
              12:          }
              13:          else if(UniChar < 0x800)
              14:          {
              15:              if ( OutUTFString )
              16:              {
              17:                  OutUTFString[UTF8CharLength++] = 0xc0 | ( UniChar >> 6 );
              18:                  OutUTFString[UTF8CharLength++] = 0x80 | ( UniChar & 0x3f );
              19:              }
              20:              else
              21:              {
              22:                  UTF8CharLength += 2;
              23:              }
              24:          }
              25:          else if(UniChar < 0x10000 )
              26:          {
              27:              if ( OutUTFString )
              28:              {
              29:                  OutUTFString[UTF8CharLength++] = 0xe0 | ( UniChar >> 12 );
              30:                  OutUTFString[UTF8CharLength++] = 0x80 | ( (UniChar >> 6) & 0x3f );
              31:                  OutUTFString[UTF8CharLength++] = 0x80 | ( UniChar & 0x3f );
              32:              }
              33:              else
              34:              {
              35:                  UTF8CharLength += 3;
              36:              }
              37:          }
              38:          else if( UniChar < 0x200000 ) 
              39:          {
              40:              if ( OutUTFString )
              41:              {
              42:                  OutUTFString[UTF8CharLength++] = 0xf0 | ( (int)UniChar >> 18 );
              43:                  OutUTFString[UTF8CharLength++] = 0x80 | ( (UniChar >> 12) & 0x3f );
              44:                  OutUTFString[UTF8CharLength++] = 0x80 | ( (UniChar >> 6) & 0x3f );
              45:                  OutUTFString[UTF8CharLength++] = 0x80 | ( UniChar & 0x3f );
              46:              }
              47:              else
              48:              {
              49:                  UTF8CharLength += 4;
              50:              }
              51:   
              52:          }
              53:   
              54:          return UTF8CharLength;
              55:      }

             

            當OutUnicodeString為NULL時, 可以進行輸出的Unicode字符串長度探測

             

               1:  uint32 UTF8StrToUnicode( const char* UTF8String, uint32 UTF8StringLength, wchar_t* OutUnicodeString, uint32 UnicodeStringBufferSize )
               2:      {
               3:          uint32 UTF8Index = 0;
               4:          uint32 UniIndex = 0;
               5:   
               6:          while ( UTF8Index < UTF8StringLength )
               7:          {
               8:              unsigned char UTF8Char = UTF8String[UTF8Index];
               9:   
              10:              if ( UnicodeStringBufferSize != 0 && UniIndex >= UnicodeStringBufferSize )
              11:                  break;
              12:   
              13:              if ((UTF8Char & 0x80) == 0) 
              14:              {
              15:                  const uint32 cUTF8CharRequire = 1;
              16:   
              17:                  // UTF8字碼不足
              18:                  if ( UTF8Index + cUTF8CharRequire > UTF8StringLength )
              19:                      break;
              20:   
              21:                  if ( OutUnicodeString )
              22:                  {
              23:                      wchar_t& WideChar = OutUnicodeString[UniIndex]; 
              24:   
              25:                      WideChar = UTF8Char;
              26:                  }
              27:   
              28:                  UTF8Index++;
              29:                  
              30:              } 
              31:              else if((UTF8Char & 0xE0) == 0xC0)  ///< 110x-xxxx 10xx-xxxx
              32:              {
              33:                  const uint32 cUTF8CharRequire = 2;
              34:   
              35:                  // UTF8字碼不足
              36:                  if ( UTF8Index + cUTF8CharRequire > UTF8StringLength )
              37:                      break;
              38:   
              39:                  if ( OutUnicodeString )
              40:                  {
              41:                      wchar_t& WideChar = OutUnicodeString[UniIndex]; 
              42:                      WideChar  = (UTF8String[UTF8Index + 0] & 0x3F) << 6;
              43:                      WideChar |= (UTF8String[UTF8Index + 1] & 0x3F);
              44:                  }
              45:                  
              46:                  UTF8Index += cUTF8CharRequire;
              47:              }
              48:              else if((UTF8Char & 0xF0) == 0xE0)  ///< 1110-xxxx 10xx-xxxx 10xx-xxxx
              49:              {
              50:                  const uint32 cUTF8CharRequire = 3;
              51:   
              52:                  // UTF8字碼不足
              53:                  if ( UTF8Index + cUTF8CharRequire > UTF8StringLength )
              54:                      break;
              55:   
              56:                  if ( OutUnicodeString )
              57:                  {
              58:                      wchar_t& WideChar = OutUnicodeString[UniIndex]; 
              59:   
              60:                      WideChar  = (UTF8String[UTF8Index + 0] & 0x1F) << 12;
              61:                      WideChar |= (UTF8String[UTF8Index + 1] & 0x3F) << 6;
              62:                      WideChar |= (UTF8String[UTF8Index + 2] & 0x3F);
              63:                  }
              64:                  
              65:   
              66:                  UTF8Index += cUTF8CharRequire;
              67:              } 
              68:              else if((UTF8Char & 0xF8) == 0xF0)  ///< 1111-0xxx 10xx-xxxx 10xx-xxxx 10xx-xxxx 
              69:              {
              70:                  const uint32 cUTF8CharRequire = 4;
              71:   
              72:                  // UTF8字碼不足
              73:                  if ( UTF8Index + cUTF8CharRequire > UTF8StringLength )
              74:                      break;
              75:   
              76:                  if ( OutUnicodeString )
              77:                  {
              78:                      wchar_t& WideChar = OutUnicodeString[UniIndex]; 
              79:   
              80:                      WideChar  = (UTF8String[UTF8Index + 0] & 0x0F) << 18;
              81:                      WideChar  = (UTF8String[UTF8Index + 1] & 0x3F) << 12;
              82:                      WideChar |= (UTF8String[UTF8Index + 2] & 0x3F) << 6;
              83:                      WideChar |= (UTF8String[UTF8Index + 3] & 0x3F);
              84:                  }
              85:   
              86:                  UTF8Index += cUTF8CharRequire;
              87:              } 
              88:              else ///< 1111-10xx 10xx-xxxx 10xx-xxxx 10xx-xxxx 10xx-xxxx 
              89:              {
              90:                  const uint32 cUTF8CharRequire = 5;
              91:   
              92:                  // UTF8字碼不足
              93:                  if ( UTF8Index + cUTF8CharRequire > UTF8StringLength )
              94:                      break;
              95:   
              96:                  if ( OutUnicodeString )
              97:                  {
              98:                      wchar_t& WideChar = OutUnicodeString[UniIndex]; 
              99:   
             100:                      WideChar  = (UTF8String[UTF8Index + 0] & 0x07) << 24;
             101:                      WideChar  = (UTF8String[UTF8Index + 1] & 0x3F) << 18;
             102:                      WideChar  = (UTF8String[UTF8Index + 2] & 0x3F) << 12;
             103:                      WideChar |= (UTF8String[UTF8Index + 3] & 0x3F) << 6;
             104:                      WideChar |= (UTF8String[UTF8Index + 4] & 0x3F);
             105:                  }
             106:   
             107:                  UTF8Index += cUTF8CharRequire;
             108:              }
             109:   
             110:   
             111:              UniIndex++;
             112:          }
             113:   
             114:          return UniIndex;
             115:      }

            療效: 用了此代碼啊, 再也不用被iconv折磨了

            posted @ 2012-02-27 14:21 戰魂小筑 閱讀(4693) | 評論 (9)編輯 收藏

            hash_map不是標準庫,因此不同平臺下包含頭文件不同, 前綴也不同,這里使用了一個通用定義

               1:  #ifdef _WIN32
               2:      #include <hash_map>
               3:      #define HASHMAP_PREFIX stdext
               4:  #else
               5:      #include <ext/hash_map>
               6:      #define HASHMAP_PREFIX __gnu_cxx    
               7:  #endif

            對于初始桶大小設置,Linux下使用hash_map構造函數可以設置, Windows下則沒有對應的設置函數.

            查閱Windows下hash_map的源碼,并在hash_map()默認構造函數旁邊添加一個測試用初始桶設置函數

               1:      hash_map( size_type _Buckets )
               2:          : _Mybase(key_compare(), allocator_type())
               3:      {
               4:          _Init( _Buckets );
               5:      }

            接下來使用相同的測試代碼

               1:      const uint32 Buckets = 1000;
               2:      HASHMAP_PREFIX::hash_map<uint32,uint32> MyHash( Buckets );
               3:   
               4:      TimeRuler Ruler;
               5:      for ( uint32 i = 0; i <1000000;i++)
               6:      {
               7:          MyHash[i] = i;
               8:      }
               9:   
              10:      printf("%d\n", Ruler.GetCostTime() );

            這里的TimeRuler是使用boost timer的時間戳封裝

            Release下測試結果:

                OS \ Buckets           8 ( default )         1000
                 Win7          430ms       560ms
                 Mint( VMware )          127ms       127ms

             

            Windows的測試結果說明, 不給出桶初始化函數是正確的, 默認管理比自己設置更高效.

            Linux平臺感覺很詭異, 不清楚是不是虛擬機造成的結果不準確

            posted @ 2012-02-23 18:54 戰魂小筑 閱讀(1579) | 評論 (0)編輯 收藏

            之前看了網上一篇文章介紹luabind, 發現這種編譯出來的luabind只會安裝debug版本, release版本的so依然坦然的躺在工程目錄

            查閱bjam的參數說明及luabind的jamroot文件第240行有如下文字

            install stage
              : luabind
              : <location>$(stage-locate)
                <install-no-version-symlinks>on
                <install-dependencies>on
                <install-type>LIB
              ;

            說明參數應該是這樣的: bjam install [stage]

            而且文章中給出的是bjam install 因此默認出調試版也是正確的, 而且估計作者只編譯了調試版就沒有處理release版了

            正確的luabind編譯法應該是:

            export BOOST_ROOT=/home/davy/dev/boost_1_48_0

            export LUA_PATH=/usr/local/

            /home/davy/dev/boost_1_48_0/bjam stage --toolset=gcc --with-date_time --with-fpic --with-filesystem link=static debug release

            /home/davy/dev/boost_1_48_0/bjam install debug

            /home/davy/dev/boost_1_48_0/bjam install release

             

            我這里必須指明bjam是因為boost的bjam版本高于默認安裝的版本, 因此使用高版本編譯

            posted @ 2012-02-21 11:23 戰魂小筑 閱讀(2672) | 評論 (1)編輯 收藏

            默認的, VC調試器只能正常顯示ANSI字符串及UNICODE字符串, 而UTF-8字符串及其他格式則無法顯示

            這里無需編寫插件及修改配置文件,只需要將要顯示的字符串拉到Watch中,并在變量后面添加,s8即可顯示

            image --> image

            同樣類型的功能也應該很熟悉

            ,數字  將變量拆分為數組顯示, 數字是要顯示多少位, 此法對const char*這類原始字符串非常有用

            ,x 16進制查看

            ,hr  查看Windows HRESULT解釋

            ,wm Windows消息,例如0x0010, wm 顯示 WM_CLOSE

            posted @ 2012-02-14 15:21 戰魂小筑 閱讀(7079) | 評論 (3)編輯 收藏

            僅列出標題
            共26頁: First 6 7 8 9 10 11 12 13 14 Last 
            91性高湖久久久久| 精品久久久久久无码中文字幕一区| 中文字幕无码免费久久| 精品久久久久久无码中文野结衣| 久久精品无码专区免费青青| 久久综合九色综合网站| 三级韩国一区久久二区综合| 久久精品成人一区二区三区| 久久久久国产亚洲AV麻豆| 99久久夜色精品国产网站| 情人伊人久久综合亚洲| 久久亚洲欧美日本精品| 久久99久久无码毛片一区二区| 国产A级毛片久久久精品毛片| 天天爽天天爽天天片a久久网| 亚洲国产天堂久久综合网站| 精品久久久久中文字| 久久综合伊人77777| 久久久这里有精品| 五月丁香综合激情六月久久| 国内精品伊人久久久久av一坑| 国产精品久久成人影院| 99热成人精品免费久久| 久久伊人色| 欧美午夜精品久久久久免费视| 久久99国产乱子伦精品免费| 成人亚洲欧美久久久久| 中文字幕精品无码久久久久久3D日动漫 | A级毛片无码久久精品免费| 久久99国产一区二区三区| 国产精品久久婷婷六月丁香| 亚洲国产精品无码久久一区二区| 精品久久久久久无码中文字幕一区| 热久久国产精品| 久久久久久久女国产乱让韩| 国产欧美久久久精品| 亚洲欧洲精品成人久久奇米网| 欧美熟妇另类久久久久久不卡| 久久国产免费直播| 国产精品美女久久久久网| 久久久久亚洲国产|