• <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>

            戰(zhàn)魂小筑

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

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

            #

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

            image

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

            這樣的設(shè)定無法啟動調(diào)試器, gdb將報錯, 無法找到調(diào)試程序:

            image

            研究了一下, 發(fā)現(xiàn)設(shè)定項里引導(dǎo)你使用瀏覽目錄對話框進(jìn)行選擇, 嘗試一下, 將Program改為絕對路徑

            image

            F5開始調(diào)試, 不報錯, main中使用getcwd獲取當(dāng)前路徑驗證, 設(shè)置正確, 問題解決

             

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

            但是對于產(chǎn)品來說是失敗的

            VisualStudio的調(diào)試器與IDE結(jié)合緊密, 因此以產(chǎn)品思想開發(fā)程序, 就能避免這種類似的問題

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

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

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

             

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

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

             

              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 戰(zhàn)魂小筑 閱讀(1874) | 評論 (0)編輯 收藏

            以下代碼使用luabind進(jìn)行l(wèi)ua的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類成員函數(shù)到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中有個手誤而造成的錯誤, 導(dǎo)致C++代碼運行到第7行時彈出assert

            位于:luabind-0.9.1\luabind\detail\call_function.hpp 第264行,對應(yīng)以下代碼第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行代碼中調(diào)用的是lua_resume, 返回的是運行錯誤, 但是被13行的assert擋住了, 無法通過第16行拋出異常被外面捕獲.

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

             

            對于lua的coroutine, 網(wǎng)上資料不多, 這里有一篇比較詳細(xì)的代碼

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

            歡迎各位有此經(jīng)驗的討論

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

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

            廢話不多說, 看代碼

               1:  -- 創(chuàng)建沙盒
               2:  function SpawnSandBox( )
               3:   
               4:      local SandBoxGlobals = {}
               5:      
               6:      -- 基礎(chǔ)函數(shù)添加
               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:  -- 在沙盒內(nèi)執(zhí)行腳本, 出錯時返回錯誤, 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行執(zhí)行結(jié)果是

             

               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行由于沒有注冊這個全局函數(shù), 因此無法訪問
            Response=    [string "ProtectedFunction()"]:1: attempt to call global 'ProtectedFunction' (a nil value)
             
            58行在全局環(huán)境中加上了這個函數(shù),因此在60行訪問正常
            protected func
            Response=    nil
             
            posted @ 2012-03-02 09:40 戰(zhàn)魂小筑 閱讀(4221) | 評論 (0)編輯 收藏

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

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

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

            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)

             

            我們發(fā)現(xiàn)第一行的so沒有對應(yīng)的庫地址, 因此我們使用awk的腳本功能,判斷第三個參數(shù),也就是=>之后的路徑必須包含/

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

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

            1.1 為進(jìn)程添加守護進(jìn)程

            參考鏈接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); //父進(jìn)程,退出 
              17:   
              18:          else if(pid < 0) exit(1); //fork失敗 
              19:   
              20:          /* 子進(jìn)程繼續(xù)執(zhí)行 */ 
              21:          setsid(); //創(chuàng)建新的會話組,子進(jìn)程成為組長,并與控制終端分離 
              22:   
              23:          /* 防止子進(jìn)程(組長)獲取控制終端 */ 
              24:          if(pid = fork()) exit(0); //父進(jìn)程,退出 
              25:   
              26:          else if(pid < 0) exit(1); //fork錯誤,退出 
              27:   
              28:          /* 第二子進(jìn)程繼續(xù)執(zhí)行 , 第二子進(jìn)程不再是會會話組組長*/ 
              29:   
              30:          //for(i = 0; i < NOFILE; i++) /* 關(guān)閉打開的文件描述符*/ 
              31:          //{ 
              32:          //close(i); 
              33:          //} 
              34:          chdir("/tmp"); /* 切換工作目錄 */ 
              35:          umask(0); /* 重設(shè)文件創(chuàng)建掩碼 */ 
              36:          return; 
              37:  }
              38:   
              39:  int main(int argc, char* argv[])
              40:  {    
              41:      FILE *fp; 
              42:   
              43:      signal(SIGCHLD, SIG_IGN); /* 忽略子進(jìn)程結(jié)束信號,防止出現(xiàn)僵尸進(jìn)程 */ 
              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 編寫服務(wù)腳本

            參考鏈接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 創(chuàng)建服務(wù)

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

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

            chmod +x ./wkcenter

            如果不設(shè)置啟動, 那么service中將無法找到該服務(wù)及操作

            1.4 設(shè)置啟動順序

            創(chuàng)建啟動鏈接

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

            創(chuàng)建關(guān)閉鏈接

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

            1.5 添加服務(wù)

            chkconfig --add wkcenter

            查看服務(wù)是否存在

            chkconfig –-list | grep wkcenter

            查看服務(wù)狀態(tài)

            chkconfig wkcenter on

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

            1.6 測試

            臨時開啟命令測試

            service wkcenter start

            1.7 QA

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

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

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

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

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

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

            當(dāng)OutUTFString為NULL時, 可以進(jìn)行輸出的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:      }

             

            當(dāng)OutUnicodeString為NULL時, 可以進(jìn)行輸出的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 戰(zhàn)魂小筑 閱讀(4701) | 評論 (9)編輯 收藏

            hash_map不是標(biāo)準(zhǔn)庫,因此不同平臺下包含頭文件不同, 前綴也不同,這里使用了一個通用定義

               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

            對于初始桶大小設(shè)置,Linux下使用hash_map構(gòu)造函數(shù)可以設(shè)置, Windows下則沒有對應(yīng)的設(shè)置函數(shù).

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

               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下測試結(jié)果:

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

             

            Windows的測試結(jié)果說明, 不給出桶初始化函數(shù)是正確的, 默認(rèn)管理比自己設(shè)置更高效.

            Linux平臺感覺很詭異, 不清楚是不是虛擬機造成的結(jié)果不準(zhǔn)確

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

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

            查閱bjam的參數(shù)說明及l(fā)uabind的jamroot文件第240行有如下文字

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

            說明參數(shù)應(yīng)該是這樣的: bjam install [stage]

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

            正確的luabind編譯法應(yīng)該是:

            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版本高于默認(rèn)安裝的版本, 因此使用高版本編譯

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

            默認(rèn)的, VC調(diào)試器只能正常顯示ANSI字符串及UNICODE字符串, 而UTF-8字符串及其他格式則無法顯示

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

            image --> image

            同樣類型的功能也應(yīng)該很熟悉

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

            ,x 16進(jìn)制查看

            ,hr  查看Windows HRESULT解釋

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

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

            僅列出標(biāo)題
            共26頁: First 6 7 8 9 10 11 12 13 14 Last 
            亚洲国产成人精品久久久国产成人一区二区三区综 | 久久婷婷五月综合国产尤物app| 一个色综合久久| 97久久国产亚洲精品超碰热| 久久香蕉综合色一综合色88| 久久久中文字幕日本| 久久国产热精品波多野结衣AV| 狠狠色丁香婷婷综合久久来来去| 香蕉久久久久久狠狠色| 久久精品国产福利国产秒| 精品国产乱码久久久久软件| 亚洲狠狠久久综合一区77777| 国产亚洲美女精品久久久2020| 国产高清国内精品福利99久久| 婷婷伊人久久大香线蕉AV | 中文字幕一区二区三区久久网站 | 99久久国产综合精品五月天喷水 | 久久久久亚洲AV无码观看| 亚洲国产精品久久66| 久久精品国产亚洲AV高清热| 久久久亚洲欧洲日产国码是AV | 久久久久人妻精品一区二区三区 | 一本色道久久88—综合亚洲精品| 国产精品无码久久久久| 99久久精品国产毛片| 九九99精品久久久久久| 国产麻豆精品久久一二三| 亚洲欧美日韩中文久久| 亚洲精品高清国产一线久久| 精品久久久中文字幕人妻| 久久婷婷午色综合夜啪| 中文成人久久久久影院免费观看| 久久人人爽人人爽人人片AV麻豆 | 久久免费99精品国产自在现线| 色偷偷888欧美精品久久久| 久久被窝电影亚洲爽爽爽| 久久精品免费一区二区三区| 99久久国产热无码精品免费| 国产精品久久成人影院| 久久青青草原国产精品免费| 国产高潮国产高潮久久久91 |