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

            #

            先說下我的工程目錄

            ProjectName\

            src\

              core\

              share\

              proj.android\

                jni\

                …

            sdk\

              protobuf-2.4.1\

                src\

                …

            從Google code下載protobuf-2.4.1源碼包, 解壓, 在protobuf-2.4.1目錄下添加Android.mk, 內容如下

            LOCAL_PATH := $(call my-dir)
             
            include $(CLEAR_VARS)
             
            LOCAL_MODULE := protobuf-2.4.1
             
            LOCAL_SRC_FILES := \
            src/google/protobuf/io/coded_stream.cc                \
            src/google/protobuf/io/printer.cc                     \
            src/google/protobuf/io/gzip_stream.cc                 \
            src/google/protobuf/io/tokenizer.cc                   \
            src/google/protobuf/io/zero_copy_stream.cc            \
            src/google/protobuf/io/zero_copy_stream_impl.cc       \
            src/google/protobuf/io/zero_copy_stream_impl_lite.cc  \
            src/google/protobuf/stubs/common.cc                   \
            src/google/protobuf/stubs/once.cc                     \
            src/google/protobuf/stubs/structurally_valid.cc       \
            src/google/protobuf/stubs/strutil.cc                  \
            src/google/protobuf/stubs/substitute.cc               \
            src/google/protobuf/compiler/importer.cc              \
            src/google/protobuf/compiler/parser.cc                \
            src/google/protobuf/descriptor.cc                     \
            src/google/protobuf/descriptor.pb.cc                  \
            src/google/protobuf/descriptor_database.cc            \
            src/google/protobuf/dynamic_message.cc                \
            src/google/protobuf/extension_set.cc                  \
            src/google/protobuf/extension_set_heavy.cc            \
            src/google/protobuf/generated_message_reflection.cc   \
            src/google/protobuf/generated_message_util.cc         \
            src/google/protobuf/message.cc                        \
            src/google/protobuf/message_lite.cc                   \
            src/google/protobuf/reflection_ops.cc                 \
            src/google/protobuf/repeated_field.cc                 \
            src/google/protobuf/service.cc                        \
            src/google/protobuf/text_format.cc                    \
            src/google/protobuf/unknown_field_set.cc              \
            src/google/protobuf/wire_format.cc                    \
            src/google/protobuf/wire_format_lite.cc               \
             
             
            LOCAL_C_INCLUDES := $(LOCAL_PATH) \
                                $(LOCAL_PATH)/src
                               
             
            include $(BUILD_STATIC_LIBRARY)

            此時編譯會報config.h找不到的錯誤, 這個文件在vsproject目錄有, 但只是VC編譯使用,  這篇文章說需要手動創建, 但實際上, Linux下可以通過config系統自動生成的, 但是Android平臺下,不使用cygwin時, 就需要自己手動創建config.h, 內容如下

            /*
                This make file is only for android ONLY, modified by Davy Xu June 17, 2013
                Cause android platform can't use linux config system when cygwin envirement is not available
            */
             
            /* the location of <hash_set> */
            #define HASH_SET_H <ext/hash_set>
            #define HASH_MAP_H <ext/hash_map>
            #define HASH_NAMESPACE __gnu_cxx
             
            /* define if the compiler has hash_map */
            //#define HAVE_HASH_MAP 1
             
            /* define if the compiler has hash_set */
            //#define HAVE_HASH_SET 1
             
            #define HAVE_PTHREAD

            剩下的事情就簡單了, 在你的工程Android.mk里添加protobuf的引用

            例如:

            LOCAL_WHOLE_STATIC_LIBRARIES += protobuf-2.4.1

            $(call import-module,protobuf-2.4.1)

            還要在NDK_MODULE_PATH中增加搜索路徑D:\Develop\ProjectName\sdk\

            注意, 這里protobuf-2.4.1名稱必須與sdk下的文件夾名, LOCAL_MODULE中的名稱保持一致, 否則搜索不到

            posted @ 2013-06-17 11:40 戰魂小筑 閱讀(5443) | 評論 (0)編輯 收藏

            最近將cocos2dx的程序移植到Android上, 某階段突然發現開始閃退. 日志方式跟了很久, 發現有內存被修改. 因為不能像VC那樣有內存斷點, 只有靠日志繼續跟蹤, 繞了很久, 終于發現一個問題

            CCApplication::sharedApplication()->run(); 在Windows下除了初始化回調外, 還有Windows平臺特殊的消息循環. 既然是循環, 這個run函數會一直阻塞到程序退出, 因此我自然的在run后添加自己的資源卸載

            換到Android上呢CCApplication::sharedApplication()->run();的實現變了. 由于Android上沒有Windows的消息循環, 所有事件都是通過java方式的事件通知. 因此CCApplication::sharedApplication()->run();變成了非阻塞, 可是我在run后添加了資源卸載. 結果導致系統剛初始化就卸載了資源, 內存直接不可用, 導致后面cocos2dx的API部分使用無問題, 而自己引擎的API調用閃退.

            cocos2dx的這個run函數命名有嚴重問題.. 被坑了好久, 還一直懷疑NDK內存管理是否有特殊之處, 殊不知..

            posted @ 2013-06-14 17:15 戰魂小筑 閱讀(9804) | 評論 (5)編輯 收藏

            本文整個部署過程無需下載及安裝使用Cygwin環境, 以下部署過程需要用到的程序及版本

            請注意下載對應你系統的版本, 64位系統請保證后文全系使用64位程序, 以免遇到不必要的麻煩

            1.JDK&JRE       JAVA運行時及開發包

            2.ADT               是Eclipse的一個插件,這一步是為了管理安卓開發庫

            http://developer.android.com/sdk/index.html

            作為新手, 請下載ADT Bundle For Windows, 這個版本已經包含

            ADK(安卓開發包), CDT(Eclipse的C/C++開發插件)及對應的Eclipse, 可以避免第一次部署出現的各種煩心!

            3.NDK              只有ADT已經可以運行普通的Andriod程序,但是如果需要編譯C/C++程序, 還需要NDK

            http://developer.android.com/tools/sdk/ndk/index.html

            4. cocos2dx 2.0.4版本

             

            準備SDK API

            下載好ADT后解壓, 有如下目錄

            eclipse\      <- 開發環境

            sdk\           <- Andriod SDK

            SDK Manager.exe     <-- Android開發包管理器, 由于Andriod版本較多, 所以此管理器可以方便開發者選擇部署目標機器

            打開SDK Manager在Android 2.2(API 8)里的 SDK Platform, Google APIs前打勾, 點擊右下角的Instal packages

            如果感覺下載速度慢, 可以移步這里http://my.oschina.net/heguangdong/blog/17443, 選擇Andriod離線下載

            這里是下載鏈接

            http://dl-ssl.google.com/android/repository/google_apis-8_r02.zip

            http://dl-ssl.google.com/android/repository/android-2.2_r02-windows.zip

            https://dl-ssl.google.com/android/repository/usb_driver_r04-windows.zip

            把android開頭的文件解壓到platforms目錄下

            把goole_apis開頭的文件解壓到add-ons目錄下

            把usb_driver_r03-windows.zip解壓到usb_driver目錄下。

            Eclipse導入工程

            打開Eclipse

            導入Cocos2dx例子工程:

            Eclipse中File->New->Other...選擇Andriod Project from Existing Code

            在Import Projects的Root Directory中導入D:\Develop\RevWar\sdk\cocos2d-2.0-x-2.0.4\samples\HelloCpp\proj.android\

            注意, 不要選中 Copy project into workspace, 否則路徑編亂很難編譯成功

             

            導入cocos2dx的java框架

            在src目錄中new package, 輸入org.cocos2dx.lib, 在org.cocos2dx.lib的package中點Import-> FileSystem

            選中目錄D:\Develop\RevWar\sdk\cocos2d-2.0-x-2.0.4\cocos2dx\platform\android\java\src\org\cocos2dx\lib\, 點選所有java文件

            工程Properties->Builder->New->Program

            在Main標簽中填寫

            填寫NDK編譯命令行 D:\Develop\android-ndk-r8e\ndk-build.cmd

            點擊Browser Workspace選中當前工程,出現${workspace_loc:/HelloCpp}

            切換到Environment標簽中填寫

            新建NDK_MODULE_PATH 填寫D:\Develop\RevWar\sdk\cocos2d-2.0-x-2.0.4\;D:\Develop\RevWar\sdk\cocos2d-2.0-x-2.0.4\cocos2dx\platform\third_party\android\prebuilt\

            修改cocos2dx的Android.mk, diff如下

            @@ -153,6 +153,7 @@

            LOCAL_WHOLE_STATIC_LIBRARIES += cocos_jpeg_static

            LOCAL_WHOLE_STATIC_LIBRARIES += cocos_libxml2_static

            LOCAL_WHOLE_STATIC_LIBRARIES += cocos_libtiff_static

            +LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static

            # define the macro to compile through support/zip_support/ioapi.c              

            LOCAL_CFLAGS := -DUSE_FILE32API

            @@ -164,3 +165,4 @@

            $(call import-module,libpng)

            $(call import-module,libxml2)

            $(call import-module,libtiff)

            +$(call import-module,CocosDenshion/android)

            F&Q

            andriod-8問題

            修改D:\Develop\RevWar\sdk\cocos2d-2.0-x-2.0.4cocos2dx\platform\android\java\project.properties中的target=android-8改成你需要的版本

            resources.ap_ does not exist

            assert目錄中有資源出問題, 排查即可

            例如: cocos2d-2.0-x-2.0.4\samples\TestCpp\proj.android\assets\Images\*.pvr.gz

            啟動Android模擬器時的Failed to allocate memory: 8問題

            調整內存值,請求內存太大導致

            api版本過低導致JAVA Symbol未定義問題

            setEGLContextClientVersion undefined

            api8(andriod 2.2)后的版本, 才支持openGL es 2.0

            自己做工程遇到的問題D:\Develop\RevWar\sdk\cocos2d-2.0-x-2.0.4\/cocos2dx/platform/android/jni/JniHelper.h:28:18: fatal error: string: No such file or directory

            將cocos2dx例子中的Application.mk拷過來, 修改下內部名稱即可

            調試請盡量使用真機, 模擬器速度很慢

            小米2默認只能管理文件, 無法用adb 連接, 因此需要安裝驅動, USB驅動直接在插入電腦后的虛擬盤里找.. 這個太坑了..

            保證每次都能部署最新的程序

            請執行每次Clean, Build project, Debug.  真機上在需要時, 會彈出安裝...

            Android啟動日志

            帶有ADT的Eclipse中有一個logcat窗口, 里面有系統及程序本身的日志, 可以做過濾,方便檢查問題. 如需自己打日志, 可以使用cocos2dx中的LOGD宏來做, 原型是__android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

             

            Remark

            添加assert后, F5刷新后再編譯
            NDK build時,默認從工程的jni目錄開始

            Andriod.mk的import 原則$(call import-module,模塊名) 這里的模塊名必須與目錄名, 模塊make file中的名稱報紙一致

            參考文章

            http://www.cnblogs.com/ybgame/archive/2012/06/07/2540693.html

            發文時, Andriod Studio已經發布了一段時間, 雖然是測試版, 但將代表未來更方便的Andriod發布工具

            posted @ 2013-06-09 17:55 戰魂小筑 閱讀(19056) | 評論 (0)編輯 收藏

               最近開始弄cocos2dx, 圖片需要整合成POT的優化紋理, 使用texturePacker來做
            下載http://www.codeandweb.com/texturepacker/download
            工具本身不是免費的, 但是可以通過申請獲得免費的Licence, 點這里
            條件是有一個自己的博客, 并且從事游戲/軟件/網頁方面的開發, 且近期有5篇文章發表
            作者特別強調,微博不等于博客

            填寫好郵箱地址,要不了幾個小時就可以獲取到序列號
            posted @ 2013-06-05 15:44 戰魂小筑 閱讀(2531) | 評論 (1)編輯 收藏

            https://code.google.com/p/protoc-gen-lua/ 下載網易兄弟寫的lua的protobuf插件(網易都把pb給弄完了,as3的也是他們寫的..)

             

            編譯python版的protobuf模塊

            https://code.google.com/p/protobuf/downloads/list 下載官方的原生版本protobuf, 這里發文時使用的是2.4.1版本

            編譯出protoc執行文件, 放一份在protobuf-2.4.1\src\下

            下載python2.7版本, 在protobuf-2.4.1\python下運行python setup.py install(如果找不到python請給python絕對路徑)

            這一步, python會下一個蛋( 真的是一個python的egg文件 ), 然后編譯出python版本的protobuf模塊放置在python下

             

            制作protoc-gen-lua的批處理

            放一份protoc在protoc-gen-lua的plugin目錄

            編寫批處理:protoc-gen-lua.bat

            @python "%~dp0protoc-gen-lua"

             

            協議目錄生成腳本

            在你需要放置協議的目錄編寫如下批處理

            buildproto.bat

            rd /S /Q .\%1%
            "..\..\src\protoc-gen-lua\plugin\protoc.exe" --plugin=protoc-gen-lua="..\..\src\protoc-gen-lua\plugin\protoc-gen-lua.bat" --lua_out=. %1%.proto

            注意protoc.exe及protoc-gen-lua.bat的路徑符合你的路徑

            再編寫要編譯的proto協議的批處理generate.bat

            call buildproto.bat loginsvc

            執行generate.bat后, 將會編譯同目錄下的loginsvc.proto,輸出loginsvc_pb.lua

             

            編譯鏈接lua的pb庫

            將protoc-gen-lua\protobuf\目錄拷貝到之前的協議目錄

            將其下的pb.c鏈入你的工程, 注意VS2010的VC下需要修改源碼

            1.將 #include <endian.h>修改為

            #ifndef _WIN32
                 #include <endian.h>
                 #endif

            避免在windows下缺失文件報錯.

            2. 調整struct_unpack函數前幾行為

            static int struct_unpack(lua_State *L)
            {
                uint8_t format = luaL_checkinteger(L, 1);
                size_t len;
                const uint8_t* buffer = (uint8_t*)luaL_checklstring(L, 2, &len);
                size_t pos = luaL_checkinteger(L, 3);
                uint8_t out[8];   

                buffer += pos;

            避免VS2010的VC編譯器過于標準, 嚴格要求C風格函數變量前置聲明

            在lua_State聲明后添加如下代碼

            extern "C" { int luaopen_pb (lua_State *L);}   // 注意防在命名空間外的全局聲明

                luaopen_pb( L );   // 直接注入全局pb, 避免動態加載pb.dll造成的一系列跨平臺問題

             

            lua中使用pb

            local loginsvc_pb = require “loginsvc_pb”
             
            local REQ = loginsvc_pb.CheckVersionREQ()
            local Data = REQ:SerializeToString( )
             
            local ACK = loginsvc_pb.CheckVersionACK()
            ACK:ParseFromString( Data )

             

            .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

            我的工程目錄

            script\
                    protobuf\
                        buildproto.bat
                        generate.bat
                        loginsvc_pb.lua
                        loginsvc.proto
                    Main.lua
                src\
                    protoc-gen-lua\
                        example\
                        plugin\
                        protobuf\

            posted @ 2013-04-24 15:44 戰魂小筑 閱讀(13492) | 評論 (4)編輯 收藏

            為了降低模塊間的耦合, 很多系統使用事件派發機制, 接收方無需知道派發者是誰.在Qt中,這個系統被稱作Slot&Signal, 需要配合moc代碼生成機制, 但是系統本身是線程安全的.

            這里我們討論的是lua的事件派發機制, 我將此寫成lua模塊, 方便配合cocos2dx進行邏輯處理

             

            local Global = _G
            local package = _G.package
            local setmetatable = _G.setmetatable
            local assert = _G.assert
            local table = _G.table
            local pairs = _G.pairs
            local ipairs = _G.ipairs
             
             
            module "Core.EventDispatcher"
             
            --[[
            數據層次
             
            ["EventName1"] =
            {
                ["_StaticFunc"] = { Func1, Func2 },
                
                [Object1] = { Func1, Func2 },
                [Object2] = { Func1, Func2 },
            },
             
            ["EventName2"] =
            {
                ...
            }
             
            ]]
             
            -- 默認調用函數
            local function PreInvoke( EventName, Func, Object, UserData, ... )
                
                if Object then
                    Func( Object, EventName, ... )
                else
                    Func( EventName, ... )
                end
             
            end
             
            function New( )    
                
                local NewObj = setmetatable( {}, { __index = package.loaded["Core.EventDispatcher"] } )
                
                -- 對象成員初始化
                NewObj.mPreInvokeFunc = PreInvoke
                NewObj.mEventTable = {}
                
                return NewObj
            end
             
            -- 添加
            function Add( Self, EventName, Func, Object, UserData )
             
                assert( Func )
             
                Self.mEventTable[ EventName ] = Self.mEventTable[ EventName ] or {}
                
                local Event = Self.mEventTable[ EventName ]
                
                if not Object then
                    Object = "_StaticFunc"
                end
                
                Event[Object] = Event[Object] or {}
                local ObjectEvent = Event[Object]
             
                ObjectEvent[Func] = UserData or true
                
            end
             
            -- 設置調用前回調
            function SetDispatchHook( Self, HookFunc )
                
                Self.mPreInvokeFunc = HookFunc
            end
             
             
            -- 派發
            function Dispatch( Self, EventName, ... )
             
                assert( EventName )
                
                local Event = Self.mEventTable[ EventName ]
                
                for Object,ObjectFunc in pairs( Event ) do
                    
                    if Object == "_StaticFunc" then
                            
                        for Func, UserData in pairs( ObjectFunc ) do
                            Self.mPreInvokeFunc( EventName, Func, nil, UserData, ... )    
                        end
                        
                    else
                    
                        for Func, UserData in pairs( ObjectFunc ) do
                            Self.mPreInvokeFunc( EventName, Func, Object, UserData, ... )
                        end
                    
                    end
             
                end
             
            end
             
            -- 回調是否存在
            function Exist( Self, EventName )
             
                assert( EventName )
                
                local Event = Self.mEventTable[ EventName ]
                
                if not Event then
                    return false
                end
                
                -- 需要遍歷下map, 可能有事件名存在, 但是沒有任何回調的
                for Object,ObjectFunc in pairs( Event ) do
                
                    for Func, _ in pairs( ObjectFunc ) do
                        -- 居然有一個
                        return true
                    end
                
                end
                
                
                return false
                
            end
             
            -- 清除
            function Remove( Self, EventName, Func, Object )
                
                assert( Func )
                
                local Event = Self.mEventTable[ EventName ]
                
                if not Event then
                    return
                end
                
                if not Object then
                    Object = "_StaticFunc"
                end
                
                
                local ObjectEvent = Event[Object]
                
                if not ObjectEvent then
                    return
                end
                
                ObjectEvent[Func] = nil
             
                    
            end
             
            -- 清除對象的所有回調
            function RemoveObjectAllFunc( Self, EventName, Object )
             
                assert( Object )
                
                local Event = Self.mEventTable[ EventName ]
                
                if not Event then
                    return
                end
                
                Event[Object] = nil
             
            end
             

            這里注意下, 我是將EventDispatcher.lua放置在Core目錄下, 因此需要使用require “Core.EventDispatcher”進行調用

            使用用例

             

                local EventDispatcher = require 'Core.EventDispatcher'
             
                local E = EventDispatcher.New()
             
             
                E:Add( "a", function( a, b )   print( a, b ) end )
             
                local Func = function( a )   print( a ) end 
                E:Add( "a", Func )
             
             
                E:Dispatch("a", 1, 2 )
                print( E:Exist("a"), E:Exist("b"))
             
                E:Remove("a", Func )
             
                E:Dispatch("a", 1, 2 )
                print( E:Exist("a"), E:Exist("b"))
            posted @ 2013-04-24 15:19 戰魂小筑 閱讀(7056) | 評論 (0)編輯 收藏

            Linux上跑服務器如果遇到程序崩潰是一件很苦惱的事情, 再碰到重現很難的BUG, 估計只能通過傳統的排查方法進行.

            在編寫本文前, 筆者使用過諸如libunwind等庫進行錯誤時堆棧打印, 但是其本身由于需要引用第三方庫, 使用還是稍微麻煩.

            經過Google后, 居然找到一篇好文, 其通過捕獲SIGSEGV信號, 并迫使程序進入gdb調試階段, 利用gdb強大的調試功能可以進行各種錯誤跟蹤, 此法已與Windows下程序崩潰后彈出VC調試幾乎接近.

            我在此文基礎上, 擴展了其通用性及便利性

            1. 使用gdb的 -ex參數, 在掛接程序后, 執行bt指令打出程序堆棧

            2. 將信息重定向到自定義的文件,在多進程都需要進行后臺輸出時帶來更大的靈活性, 同時也解決了gdb只能在前臺調試的問題

            代碼如下

            #include <stdio.h>
            #include <stdlib.h>
            #include <signal.h>
            #include <string.h>
            
            void dump(int signo)
            {
                    char buf[1024];
                    char cmd[1024];
                    FILE *fh;
            
                    snprintf(buf, sizeof(buf), "/proc/%d/cmdline", getpid());
                    if(!(fh = fopen(buf, "r")))
                            exit(0);
                    if(!fgets(buf, sizeof(buf), fh))
                            exit(0);
                    fclose(fh);
                    if(buf[strlen(buf) - 1] == '/n')
                            buf[strlen(buf) - 1] = '/0';
                    snprintf(cmd, sizeof(cmd), "gdb %s %d -ex=bt > ./a.txt", buf, getpid());
                    system(cmd);
            
                    exit(0);
            }

            在服務器開啟時,添加 signal(SIGSEGV, &dump ); 進行信號處理掛接即可

             

             

            引用: http://blog.csdn.net/kakaka2011/article/details/6597857  作者: kakaka2011

            posted @ 2012-12-29 17:53 戰魂小筑 閱讀(9895) | 評論 (3)編輯 收藏

            最近為服務器添加XMLSocket與Flash進行通信, 這種協議其實是一種以\0結尾的字符串協議, 為了讓asio兼容此協議, 我從文檔找到了async_read_until異步讀取系列, 這個函數的原理時, 給定一個streambuf, 和一個分隔符, asio碰到分隔符時返回, 你可以從streambuf中讀取需要的數據. 看似很簡單, 我很快寫好一個demo與Flash進行通信, 結果發現在一個echo邏輯速度很快時, 服務器居然亂包了, 網上查了下, 官方原文是這樣的:

            ”After a successful async_read_until operation, the streambuf may contain additional data beyond the delimiter. An application will typically leave that data in the streambuf for a subsequent async_read_until operation to examine.”

            意思是, streambuf中并不一定是到分隔符前的所有數據, 多余的數據可能一樣會在streambuf中. 也就是說, 還需要自己再次處理一遍數據...

            動手唄, async_read_until看似就是一個廢柴, 底層已經費了很多CPU在逐字符與分隔符的匹配上, 拋上來的數據居然還是半成品.

            代碼如下, 測試通過, 但是實在很費解為啥非要再做一次..

                      boost::asio::streambuf* SB = SBP.get();
            
                        // 訪問緩沖
                        const char* Buffs = boost::asio::buffer_cast<const char*>( SB->data() );
            
                        uint32 DataSize = 0;
                        for ( uint32 i = 0; i < SB->size(); ++i )
                        {
                            const char DChar = Buffs[i];
            
                            // 這里需要自己判斷字符串內容, read_until的文檔里這么說的
                            if ( DChar == '\0' )
                            {
                                DataSize = i;
                                break;
                            }
                        }
            
                        if ( DataSize > 0 )
                        {
                            // 取成字符串
                            std::string FullText( Buffs, DataSize );
                            
                            // 消費
                            SB->consume( DataSize );                
            
                            mWorkService->post(
                                boost::bind(&AsioSession::NotifyReadString,
                                shared_from_this(),
                                FullText )
                                );
            
                        }
              另外, 為了保證輸入性安全, 可以在streambuf構造時加一個最大一個讀取量, 超過此量會返回報錯, 避免了緩沖區被撐爆的危險
            posted @ 2012-12-03 15:12 戰魂小筑 閱讀(11593) | 評論 (5)編輯 收藏

            即便使用了Google SSL加密搜索, 由于Google需要對搜索結果進行點擊跟蹤,因此很容易被GFW重置連接. 使用以下方法可以避免此問題

            在Chrome瀏覽器中輸入chrome://net-internals/

            在HSTS標簽中輸入www.google.com

            點擊add添加即可

            posted @ 2012-09-17 23:22 戰魂小筑 閱讀(769) | 評論 (0)編輯 收藏

            網上找了很多, 真正好用的代碼不多, 自己研究了下,寫下例子備份

             

            Private Sub ConvFile(InputFile As String, OutputFile As String)
             
                Dim ReadStream As Object
                Set ReadStream = CreateObject("ADODB.Stream")
                
                Dim FileContent As String
                
                With ReadStream
                    .Type = 2               'adTypeText
                    .Charset = "UNICODE"
                    .Open
                    .LoadFromFile InputFile
                    FileContent = .ReadText
                    .Close
                    
                End With
                
                Set ReadStream = Nothing
                
                
                
                Dim WriteStream As Object
                Set WriteStream = CreateObject("ADODB.Stream")
                   
                
                With WriteStream
                    .Type = 2               'adTypeText
                    .Charset = "UTF-8"
                    .Open
                    .WriteText FileContent
                    .SaveToFile OutputFile, 2  'adSaveCreateOverWrite
                    
                    .Flush
                    .Close
                    
                End With
                
                Set WriteStream = Nothing
             
                
            End Sub

             

            上半截是讀取文件, 下半截是寫入文件, 需要轉換不同格式, 請自行更換

            posted @ 2012-09-13 19:43 戰魂小筑 閱讀(8639) | 評論 (2)編輯 收藏

            僅列出標題
            共26頁: First 4 5 6 7 8 9 10 11 12 Last 
            亚洲国产精品一区二区三区久久| 久久九九精品99国产精品| 日韩人妻无码精品久久久不卡 | 久久精品中文闷骚内射| 精品久久久久久无码不卡| 久久久久国色AV免费观看| 久久99精品免费一区二区| 久久久免费观成人影院| 久久久WWW成人免费毛片| 人人狠狠综合88综合久久| 久久无码人妻精品一区二区三区| 久久精品国产一区二区| 日韩十八禁一区二区久久| 综合久久精品色| 无码超乳爆乳中文字幕久久 | 伊人久久大香线蕉av不卡| 亚洲va国产va天堂va久久| 久久亚洲精品成人AV| 久久天堂电影网| 九九久久精品国产| 久久久精品久久久久影院| 性色欲网站人妻丰满中文久久不卡| 久久精品国产亚洲av麻豆小说| 久久99国产综合精品免费| 一本大道久久a久久精品综合| 国产精品99久久久久久宅男| 性做久久久久久久久老女人| 久久综合国产乱子伦精品免费| 欧美精品一本久久男人的天堂| 亚洲精品tv久久久久久久久久| 久久精品亚洲日本波多野结衣| 亚洲国产精品一区二区久久| 久久久久国产精品人妻| 国产99久久久久久免费看 | 国产精品99久久久久久董美香| 久久久久久国产a免费观看黄色大片| 久久偷看各类wc女厕嘘嘘| 久久久久久亚洲精品不卡| 精品熟女少妇a∨免费久久| 青青青青久久精品国产h久久精品五福影院1421| 亚洲国产美女精品久久久久∴|