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

            colorful

            zc qq:1337220912

             

            2015年10月21日

            Windows調試 - 如何使用dump文件

            http://blog.csdn.net/jfkidear/article/details/22201829
             

            Windows調試 - 如何使用dump文件

            2013-02-04 16:05 445人閱讀 評論(0) 收藏 舉報
            dmp dump debug visua

            如何使用dump文件

            我最近在開發一個windows下的程序(win7/win8),有一些case下會crash,如果在自己開發機器上調試比較簡單:運行程序,然后vs attach到進程上即可,但是在每臺QA的機器上安裝vs時不現實的,因此我們要用到dump文件。

            微軟網站有一篇文章講述如何創建dump文件:

            http://support.microsoft.com/kb/931673

            第一種: 通過任務管理器:這種適用在程序掛了(crash)的時候進程還未退出,比如我運行程序,出現了下面的錯:


            此時打開任務管理器,右擊相應進程,點擊"Create Dump File“:


            一會創建完成:


            然后把這個DMP文件拷到開發機器上,用VS打開: 會出現下面的界面,要想知道發生錯誤時候的調用棧,需要設置symbol的路徑,點擊”Set Symbol Paths“:


            注意這個pdb要對應于crash的exe,否則調用棧沒法顯示:


            設置完成后,點擊”Debug with Native Only“ 你就可以看到調用棧了。


            第二種: 改注冊表

            如果程序crash的時候沒有框蹦出來,可以通過改注冊表的設置讓操作系統在程序crash的時候自動生成dump,并放到特定的目錄下

             

            1. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps  
            2. Value Name = DumpType  
            3. Data type: REG_DWORD  
            4. Value Data = 1  

            其中Value Data=1代表的含義是:

             

             

            1. 0 = Create a custom dump  
            2. 1 = Mini dump  
            3. 2 = Full dump  

            設置完成后,crash發生時,操作系統生成dump,路徑在%LOCALAPPDATA%\CrashDumps下,詳細可以參考:

             

            http://msdn.microsoft.com/en-us/library/bb787181%28v=VS.85%29.aspx

            (完)

            posted @ 2015-10-21 15:22 多彩人生 閱讀(640) | 評論 (0)編輯 收藏

            2015年10月14日

            STL的remove函數和list的remove成員函數

            http://www.cnblogs.com/kinuxroot/archive/2013/01/25/stl_remove_problem.html

            今天看書剛剛看的,就記錄下來吧。這可能是老生常談了,權且作為一個警醒的例子吧。

            大家都知道STL有兩個非常重要的組成部分,容器和算法。

            算法就是一個個的函數,通過迭代器和容器關聯在一起,完成一些工作。

            算法和容器的分離為程序設計提供了很大的靈活性,但是也帶來了一些負面效果,下面我講的這個問題就是一個例子。

            STL的算法里有一個remove函數,而list自身也有一個remove函數,功能都是一樣的,移除某一個元素,那我們應該使用哪一個呢?

            看一下下面這段程序

            復制代碼
             1     list<int> numbers;  2   3     for ( int number = 0; number <= 6; number ++ ) {  4         numbers.push_front(number);  5         numbers.push_back(number);  6     }  7   8     copy(numbers.begin(), numbers.end(),  9             ostream_iterator<int>(cout, " ")); 10     cout << endl; 11  12     // remove algorithm will remove element but not erase the element from container 13     // it will return the logical desination of container 14     list<int>::iterator endOfNumbers = remove(numbers.begin(), numbers.end(), 3); 15  16     copy(numbers.begin(), numbers.end(), 17             ostream_iterator<int>(cout, " ")); 18     cout << endl;
            復制代碼

            輸出是什么呢?

            第一行肯定是6 5 4 3 2 1 0 0 1 2 3 4 5 6,那么第二行會輸出什么?

            如果是沒有仔細看過STL的人肯定會認為remove(number.begin(), numbers.end(), 3)會移除所有值為3的元素。所以輸出是:6 5 4 2 1 0 0 1 2 4 5 6。

            但是,我們看一下它真正的輸出:

            6 5 4 2 1 0 0 1 2 4 5 6 5 6

            你可能會非常驚訝,為什么最后會多出5和6兩個數呢?

            我們來講一下remove算法的原理。

            remove算法工作時并不是直接把元素刪除,而是用后面的元素替代前面的元素,也即是說如果我對1234這個序列remove 2,返回的序列是 1344(3被復制到2的位置,4被復制到3的位置)。

            這樣上面的例子就好解釋了,那兩個3的元素并沒有被移除,而是用后面的元素覆蓋了前面的元素。多出的那兩個數沒有被移除掉而已。

            那么我們應該如何真正完成移除呢?remove函數會返回一個迭代器,那個迭代器是這個序列的邏輯終點,也即是我代碼里的endOfNumbers,它指向倒數第二個5上。

            于是我們要利用list的erase函數完成元素移除

            numbers.erase(endOfNumbers, numbers.end());

            這樣我們就完成了我們的工作,稍稍有點曲折……

            其實我們可以把這兩步放在一起,比如如果我想接著移除所有值為2的元素

            numbers.erase(remove(numbers.begin(), numbers.end(), 2), numbers.end());

            這樣我們就可以一步到位了。

            但是這樣好么?

            不好。

            大家會發現,remove函數的原理是復制而不是指針的移動(因為函數操縱的是迭代器,而C++的迭代器沒有定義刪除操作),這樣會帶來一個問題:我們使用list是因為它的修改的效率非常高,改變一下指針就可以了。而這里我們復制了元素,如果在vector中,可能還是高效的,因為vector無論如何都要復制,而對于list就不是如此了,會極度降低我們的效率。

            那我們怎么辦呢?

            答案是使用list自己的remove函數

            numbers.remove(1);

            我們可以這樣刪除所有值為1的元素。

            也即是說,如果要刪除list中的元素,我們應該使用list的remove成員函數,而不是remove算法

            小結

            我們都知道,STL是一個效率、復用性、靈活性折衷的產物,其中效率至關重要,所以STL已經禁止了一些效率低的操作(比如list的隨機訪問),而鼓勵你去使用其它的容器。

            但是,在算法中,為了靈活性,STL還是會犧牲一些東西,比如我們這個例子。

            個人覺得,STL作為C++標準庫的一個組成部分,特點和C++本身一模一樣,強大而復雜,有些地方難以理解,很多細節需要學習注意,我們要學會避免陷入某些陷阱之中,比如這個例子就是一個效率陷阱。

            其它更多的陷阱是錯誤處理方面的,STL本身并沒有規定過多的錯誤處理,大部分的錯誤處理都交給了我們,理由很簡單:性能至上,如果一個東西自身沒有錯誤檢查,我們可以包裝一個帶錯誤檢查的類;但是如果這個東西自身就帶了錯誤檢查,那么我們就沒有任何方法提升它的效率了。這也是很多C和C++庫的設計原則。

            所以,很多時候,需要我們深入細節,然后再決定到底怎么做。因為C++就是如此:有很多路可以走,需要我們自己選擇最好的一條路。

            分類: C++

            posted @ 2015-10-14 15:50 多彩人生 閱讀(895) | 評論 (1)編輯 收藏

            2015年4月21日

            C++ 11 Lambda表達式

            http://www.cnblogs.com/hujian/archive/2012/02/14/2350306.html
            C++ 11中的Lambda表達式用于定義并創建匿名的函數對象,以簡化編程工作。Lambda的語法形式如下:
                          [函數對象參數] (操作符重載函數參數) mutable或exception聲明 ->返回值類型 {函數體}
                  可以看到,Lambda主要分為五個部分:[函數對象參數]、(操作符重載函數參數)、mutable或exception聲明、->返回值類型、{函數體}。下面分別進行介紹。
                  一、[函數對象參數],標識一個Lambda的開始,這部分必須存在,不能省略。函數對象參數是傳遞給編譯器自動生成的函數對象類的構造函數的。函數對象 參數只能使用那些到定義Lambda為止時Lambda所在作用范圍內可見的局部變量(包括Lambda所在類的this)。函數對象參數有以下形式:
                       1、空。沒有使用任何函數對象參數。
                       2、=。函數體內可以使用Lambda所在作用范圍內所有可見的局部變量(包括Lambda所在類的this),并且是值傳遞方式(相當于編譯器自動為我們按值傳遞了所有局部變量)。
                       3、&。函數體內可以使用Lambda所在作用范圍內所有可見的局部變量(包括Lambda所在類的this),并且是引用傳遞方式(相當于編譯器自動為我們按引用傳遞了所有局部變量)。
                       4、this。函數體內可以使用Lambda所在類中的成員變量。
                       5、a。將a按值進行傳遞。按值進行傳遞時,函數體內不能修改傳遞進來的a的拷貝,因為默認情況下函數是const的。要修改傳遞進來的a的拷貝,可以添加mutable修飾符。
                       6、&a。將a按引用進行傳遞。
                       7、a, &b。將a按值進行傳遞,b按引用進行傳遞。
                       8、=,&a, &b。除a和b按引用進行傳遞外,其他參數都按值進行傳遞。
                       9、&, a, b。除a和b按值進行傳遞外,其他參數都按引用進行傳遞。
                  二、(操作符重載函數參數),標識重載的()操作符的參數,沒有參數時,這部分可以省略。參數可以通過按值(如:(a,b))和按引用(如:(&a,&b))兩種方式進行傳遞。
                  三、mutable或exception聲明,這部分可以省略。按值傳遞函數對象參數時,加上mutable修飾符后,可以修改按值傳遞進來的拷貝(注意 是能修改拷貝,而不是值本身)。exception聲明用于指定函數拋出的異常,如拋出整數類型的異常,可以使用throw(int)。
                  四、->返回值類型,標識函數返回值的類型,當返回值為void,或者函數體中只有一處return的地方(此時編譯器可以自動推斷出返回值類型)時,這部分可以省略。
                  五、{函數體},標識函數的實現,這部分不能省略,但函數體可以為空。
                  下面給出了一段示例代碼,用于演示上述提到的各種情況,代碼中有簡單的注釋可作為參考。
            復制代碼
            class CTest
            {
            public:
             CTest() : m_nData(20) { NULL; }
             void TestLambda()
             {
              vector<int> vctTemp;
              vctTemp.push_back(1);
              vctTemp.push_back(2);

              // 無函數對象參數,輸出:1 2
              {
               for_each(vctTemp.begin(), vctTemp.end(), [](int v){ cout << v << endl; });
              }

              // 以值方式傳遞作用域內所有可見的局部變量(包括this),輸出:11 12
              {
               int a = 10;
               for_each(vctTemp.begin(), vctTemp.end(), [=](int v){ cout << v+a << endl; });
              }

              // 以引用方式傳遞作用域內所有可見的局部變量(包括this),輸出:11 13 12
              {
               int a = 10;
               for_each(vctTemp.begin(), vctTemp.end(), [&](int v)mutable{ cout << v+a << endl; a++; });
               cout << a << endl;
              }

              // 以值方式傳遞局部變量a,輸出:11 13 10
              {
               int a = 10;
               for_each(vctTemp.begin(), vctTemp.end(), [a](int v)mutable{ cout << v+a << endl; a++; });
               cout << a << endl;
              }

              // 以引用方式傳遞局部變量a,輸出:11 13 12
              {
               int a = 10;
               for_each(vctTemp.begin(), vctTemp.end(), [&a](int v){ cout << v+a << endl; a++; });
               cout << a << endl;
              }

              // 傳遞this,輸出:21 22
              {
               for_each(vctTemp.begin(), vctTemp.end(), [this](int v){ cout << v+m_nData << endl; });
              }

              // 除b按引用傳遞外,其他均按值傳遞,輸出:11 12 17
              {
               int a = 10;
               int b = 15;
               for_each(vctTemp.begin(), vctTemp.end(), [=, &b](int v){ cout << v+a << endl; b++; });
               cout << b << endl;
              }


              // 操作符重載函數參數按引用傳遞,輸出:2 3
              {
               for_each(vctTemp.begin(), vctTemp.end(), [](int &v){ v++; });
               for_each(vctTemp.begin(), vctTemp.end(), [](int v){ cout << v << endl; });
              }

              // 空的Lambda表達式
              {
               [](){}();
               []{}();
              }
             }

            private:
             int m_nData;
            };
            復制代碼

            posted @ 2015-04-21 10:39 多彩人生 閱讀(499) | 評論 (0)編輯 收藏

            2015年3月1日

            qcjl lua project log

            2015/3/1
            protoc-gen-lua 生成的lua又發現新的問題, main function has more than 200 local variables問題,網上搜索了一下,有相應的解決方法,據說還會有一個新的問題出來:不能用 repeated submessage,  建議用云風的pbc. 所以方案改為用云風的pbc

            posted @ 2015-03-01 11:55 多彩人生 閱讀(1572) | 評論 (0)編輯 收藏

            2015年2月12日

            cocos2dx lua protobuf

            http://blog.csdn.net/weyson/article/details/17024325
            http://www.shnenglu.com/colorful/archive/2015/01/17/209557.html
            http://blog.csdn.net/w00w12l/article/details/39316321

            protoc-gen-lua下載地址: https://github.com/sean-lin/protoc-gen-lua

            1/ 先到protobuf的python目錄下執行
                python setup.py build
                python setup.py install

            2/ 在protoc-gen-lua的plugin目錄中新建protoc-gen-lua.bat, 內容如下:
            @python 目錄\protoc-gen-lua\plugin\protoc-gen-lua

            3/ 用protoc把proto文件生成lua文件
              protoc --lua_out=./ --plugin=protoc-gen-lua="目錄\protoc-gen-lua.bat"  test.proto

            4/ 將protoc-gen-lua/protobuf下的pb.c 放到工程的Classes下, 并加入到c++工程中

            5/ 將protoc-gen-lua/protobuf上的所有lua文件放到工程的src目錄(lua目錄)下

            6/ AppDelegate.cpp 添加代碼
            extern "C"{
                int luaopen_pb(lua_State* L);
            }
            在applicationDidFinishLaunching()中調用 luaopen_pb(state);

            ---------------------------------------------------------------------------
                require "src/xy/person_pb"  
                local msg = person_pb.Person()  
                msg.id = 100   
                msg.name = "foo"   
                msg.email = "bar"   

                local pb_data = msg:SerializeToString()  -- Parse Example  
                print("create:", msg.id, msg.name, msg.email, pb_data)  


                local msg = person_pb.Person()   
                msg:ParseFromString(pb_data)   
                print("parser:", msg.id, msg.name, msg.email, pb_data)

            ---------------------------------------------------------------------------
            移植到android 記得將pb.c添加到proj.android\jni\Android.mk中

             

            posted @ 2015-02-12 11:42 多彩人生 閱讀(1556) | 評論 (0)編輯 收藏

            2015年2月6日

            error C2061: 語法錯誤: 標識符“wctomb”

            1>  pb.c
            1>e:\test003\test101\src\pb.c : warning C4819: 該文件包含不能在當前代碼頁(936)中表示的字符。請將該文件保存為 Unicode 格式以防止數據丟失
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(18): error C2054: 在“using”之后應輸入“(”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(18): error C2061: 語法錯誤: 標識符“using”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(19): error C2061: 語法錯誤: 標識符“using”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(19): error C2061: 語法錯誤: 標識符“abs”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(19): error C2059: 語法錯誤:“;”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(19): error C2061: 語法錯誤: 標識符“atexit”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(20): error C2061: 語法錯誤: 標識符“atof”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(20): error C2059: 語法錯誤:“;”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(20): error C2061: 語法錯誤: 標識符“atoi”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(20): error C2061: 語法錯誤: 標識符“atol”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(21): error C2061: 語法錯誤: 標識符“bsearch”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(21): error C2059: 語法錯誤:“;”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(21): error C2061: 語法錯誤: 標識符“calloc”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(21): error C2061: 語法錯誤: 標識符“div”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(22): error C2061: 語法錯誤: 標識符“exit”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(22): error C2059: 語法錯誤:“;”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(22): error C2061: 語法錯誤: 標識符“free”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(23): error C2061: 語法錯誤: 標識符“labs”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(23): error C2059: 語法錯誤:“;”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(23): error C2061: 語法錯誤: 標識符“ldiv”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(23): error C2061: 語法錯誤: 標識符“malloc”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(24): error C2061: 語法錯誤: 標識符“mblen”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(24): error C2059: 語法錯誤:“;”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(24): error C2061: 語法錯誤: 標識符“mbstowcs”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(24): error C2061: 語法錯誤: 標識符“mbtowc”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(25): error C2061: 語法錯誤: 標識符“qsort”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(25): error C2059: 語法錯誤:“;”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(25): error C2061: 語法錯誤: 標識符“rand”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(25): error C2061: 語法錯誤: 標識符“realloc”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(26): error C2061: 語法錯誤: 標識符“srand”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(26): error C2059: 語法錯誤:“;”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(26): error C2061: 語法錯誤: 標識符“strtod”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(26): error C2061: 語法錯誤: 標識符“strtol”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(27): error C2061: 語法錯誤: 標識符“strtoul”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(27): error C2059: 語法錯誤:“;”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(28): error C2061: 語法錯誤: 標識符“wcstombs”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(28): error C2059: 語法錯誤:“;”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(28): error C2061: 語法錯誤: 標識符“wctomb”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(30): error C2054: 在“using”之后應輸入“(”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(33): error C2061: 語法錯誤: 標識符“using”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(34): error C2061: 語法錯誤: 標識符“system”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(34): error C2059: 語法錯誤:“;”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(37): error C2061: 語法錯誤: 標識符“atoll”
            1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\cstdlib(37): error C2059: 語法錯誤:“;”
            解決方法:
            右擊.c文件,c/c++/高級,強制包含文件,如果有algorithm或者其他的,去掉,重新編譯

            posted @ 2015-02-06 10:37 多彩人生 閱讀(3401) | 評論 (0)編輯 收藏

            2015年2月5日

            fatal error C1853: "Debug\sift.pch"預編譯頭文件來自編譯器的早期版本

            該錯誤是因為當項目中混合了 .cpp 和 .c 文件時,編譯器會對它們采取不同的編譯方式(主要是因為對函數聲明的處理方式不同),
            因而不能共用一個預編譯頭文件。在 VC++ 中,默認的預編譯頭文件是針對 C++ 的 (stdafx.h 和 stdafx.cpp),當然也可以創建針對 C 的預編譯頭。

            方法:將少數的不同類文件設為不使用預編譯頭是比較平衡的做法,方法是:對于 VC++6.0,在 FileView 里對要取消預編譯頭的 .c (或 .cpp) 文件點右鍵,
            選擇 settings,在彈出的對話框右邊選擇 category 為 precompiled headers,再設置選項為 not using ...;
            (對于 VS2005,則在 solution explorer 中對相應文件點右鍵選擇 properties,在 precompiled headers 項下設置 not using... 即可。如果需要設置多個文件,
            則可以按住 Ctrl 鍵再同時選中這些文件并設置)
            PS:解釋如下點擊項目 點擊屬性 然后選擇C/C++ 預編譯頭 創建使用頭文件 不使用預編譯頭文件
            (解決方案資源管理器-右擊需要排除的c或cpp文件]-彈出屬性菜單-展開C/C++-預編譯頭-創建/使用預編譯頭-選擇不適用預編譯頭)

            posted @ 2015-02-05 18:32 多彩人生 閱讀(12572) | 評論 (0)編輯 收藏

            error C2275: “XXX”: 將此類型用作表達式非法

            在移植c++代碼到c的時候,經常會出現一個奇怪的錯誤,
            error C2275: “XXX”: 將此類型用作表達式非法

            表達式非法,這個錯誤是由于c的編譯器要求將變量的申明放在一個函數塊的頭部,而c++沒有這樣的要求造成的。


            解決的辦法就是把變量的申明全部放在變量的生存塊的開始。

            posted @ 2015-02-05 18:30 多彩人生 閱讀(6850) | 評論 (0)編輯 收藏

            2015年1月17日

            Quick-Cocos2d-x 集成 Google protobuf 方法

            http://cn.cocos2d-x.org/tutorial/show?id=506

            本文將向您介紹Quick-Cocos2d-x集成google protobuf的方法。  
             
            第一步   需要最新的protobuf 類庫和解析程序。 
            下載地址:https://github.com/sean-lin/protoc-gen-lua
             
            git clone https://github.com/sean-lin/protoc-gen-lua.git 到任意的一個地方
             

            然后,可以得到重要的兩個目錄

            1
            2
            protoc-gen-lua/plugin/ 
            protoc-gen-lua/protobuf/
             
            第二步, 需要使用protoc —lua_out=. 這種方法, 將我們自己的*.proto 的文件解析成lua文件

            plugin目錄是提供將buffer 文件解析成lua 版本的類庫, 需要python 支持。  如果已經編譯了google 官方的protoc 那個程序, 只需要在系統PATH環境變量總追加plugin目錄就好:

            1
            export PATH={protoc-gen-lua DIR }/plugin:$PATH
             
            關于protoc的編譯另請google .
             
            如果解析不出lua文件來, 可以手動志信一下plugin/protoc-gen-lua的程序, 他應該是+x 的權限(chmod +x plugin/protoc-gen-lua)
             
            細節的安裝步驟可以參考 https://code.google.com/p/protoc-gen-lua/
             
            第三步 , 將protobuf 集成到quick 中
            protoc-gen-lua/protobuf/ 目錄就是要編譯到quick-cocos2d-x目錄里面的部分。 
             
            現在, 我們只需要 protoc-gen-lua/protobuf/pb.c 這個文件 
             

            先確定自己的quick-cocos2d-x lua擴展目錄:

            1
            /quick-cocos2d-x/lib/cocos2d-x/scripting/lua/lua_extensions/
             
            所有lua 的c/c++現成擴展,都可以直接放到這里。 
              
            將pb.c這個文件復制到 lua_extension目錄下, 最好獨立一個目錄, 免得擴展多了亂。 
              

            這是我的目錄結構:

            1
            ./quick-cocos2d-x/lib/cocos2d-x/scripting/lua/lua_extensions/protobuf/pb.c
              
            然后開始修改擴展程序配置文件, lua_extensions.c
             

            路徑為:

            1
            ./quick-cocos2d-x/lib/cocos2d-x/scripting/lua/lua_extensions/lua_extensions.c
             

            目前是一個不足60行的小文件, 我打算全部貼進來:

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41
            42
            43
            44
            45
            46
            47
            48
            49
            50
            51
            52
            53
            54
            55
            56
            57
            58
            59
            60
            61
            62
            63
            64
            65
            66
            67
            68
            69
            70
            #include "lua_extensions.h" 
               
            #if __cplusplus 
            extern "C"
            #endif 
                
            // cjson 
            #include "cjson/lua_cjson.h" 
                
                
            // zlib 
            #include "zlib/lua_zlib.h" 
                
                
            // lpack 
            #include "lpack/lpack.h" 
                
                
            // socket 
            #include "socket/luasocket.h" 
            #include "socket/mime.h" 
            #include "socket/socket_scripts.h" 
                
                
            // filesystem 
            #include "filesystem/lfs.h" 
                
                
            // lsqlite3 
            #include "lsqlite3/lsqlite3.h" 
                
                
            #include "protobuf/pb.c"   //引用protobuf 庫文件 
                
                
            static luaL_Reg luax_exts[] = { 
                 {"cjson", luaopen_cjson_safe}, 
                 {"zlib", luaopen_zlib}, 
                 {"pack", luaopen_pack}, 
                 {"socket.core", luaopen_socket_core}, 
                 {"mime.core", luaopen_mime_core}, 
                 {"lfs", luaopen_lfs}, 
                 {"lsqlite3", luaopen_lsqlite3}, 
                 {NULL, NULL} 
            }; 
                
                
            void luaopen_lua_extensions(lua_State *L) 
                 // load extensions 
                 luaL_Reg* lib = luax_exts; 
                 lua_getglobal(L, "package"); 
                 lua_getfield(L, -1, "preload"); 
                 for (; lib->func; lib++) 
                 
                     lua_pushcfunction(L, lib->func); 
                     lua_setfield(L, -2, lib->name); 
                 
                 lua_pop(L, 2); 
                
                
                 // load extensions script 
                 luaopen_socket_scripts(L); 
                 luaopen_pb(L);   //這是加入的protobuf 擴展注冊名 
                
                
            #if __cplusplus 
            } // extern "C" 
            #endif
            至此 , protobuf 擴展部分就算擴展完成了。 
             
            確認是否成功支持 , 可以在quick 項目最先被調用的lua文件中追加 require "pb" 做測試。 
             
            *但這時候通過protoc 轉碼后得到的lua文件還不能被解析。 
             
            第四步 從項目中包含protobuf的 lua庫
            protoc-gen-lua/protobuf/這個目錄下面, 還有大量的.lua文件, 是用來支持proto轉碼后的文件解析調用的。 不能少了這些文件。 
             
            復制protoc-gen-lua/protobuf文件夾 到項目中 scripts目錄下。  
              

            目錄結構應該是這樣的:

            1
            [PROJECT]/scripts/protobuf/*.lua
             
            然后, 需要告訴框架,從哪里可以引用到它。 
             

            修改main.lua 在require("appxxxxxx") 上面 , 加入下面的代碼:

            1
            package.path = package.path .. ";./protobuf/?.lua;./scripts/protobuf/?.lua;"
             
            這個方法, 能保證程序在被編譯到手機之后仍然可以繼續訪問這個庫。 
              
            ***千萬別把轉碼的proto文件放到[PROJECT]/scripts/protobuf 目錄里面.不信可以試試。
             
            現在, 項目支持protobuf 文件的解析了。
             
            第五步  重新編譯player-x
            如果不習慣用player-x調試, 這個步驟不是必須的。 
             

            進入player-x qt源碼目錄 :

            1
            cd quick-cocos2d-x/player/proj.qt
             

            使用qmake 文件執行quick-x.pro 文件 

            1
            qmake ./quick-x.pro
             
            繼續:
            make 
             
            等待結束, 將得到的quick-x-player文件, 
             
            放到:quick-cocos2d-x/player/bin/mac/ 目錄下, 這樣sublime text 裝QuickXDev 擴展的直接可以用。 
              
            **如果是mac os 10.9 系統, 可能編譯不過去player-x程序。 我遇到了這個問題。 
             
            會提示錯誤  pb.c:28:10: fatal error: 'endian.h' file not found 
             

            如果錯誤信息相同, 修改文件:

            1
            ./quick-cocos2d-x/lib/cocos2d-x/scripting/lua/lua_extensions/protobuf/pb.c
             

            查找行:

            1
            #include <endian.h>
              

            臨時變更為:

            1
            #include <machine/endian.h>
              
            然后重新編譯 player-x 
             
            make 就足夠了 
             
            make
             
            **player-x 編譯完畢后, 千萬要將endian.h 引用改回原來的 #include <endian.h> , 否則打包到手機的時候又回提示文件找不到了。 

            posted @ 2015-01-17 16:08 多彩人生 閱讀(1944) | 評論 (0)編輯 收藏

            Lua注冊回調到C++

            http://cn.cocos2d-x.org/tutorial/show?id=1896

            思路

            像所有語言一樣,綁定回調主要是執行的任務執行到特定情形的時候,調用對用回調方法。 本文也一樣,Lua注冊回調到C++的核心思路是,當C代碼執行到特定特定情形的時候,調用Lua的方法。

            我這里使用的是用lua_stack直接調用lua的方法,沒有使用Cocos2d-x封裝的那個dispatcher,因為熟悉那個格式太墨跡了。


            主要步驟如下

            • 緩存Lua函數在Lua環境中的引用

            • 在C代碼的地方用C的方式設置好回調

            • 在C代碼回調函數執行的時候,調用lua函數


            實現

            • C代碼綁定回調,調用Lua函數

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            void ArmatureNode::registerMovementEventHandler(int handler)
            {
                unregisterMovementEventHandler();  //移除之前注冊的監聽
                _movementHandler = handler;         //緩存lua函數的引用 這個后邊說
                 
                auto dispatcher = getCCEventDispatcher();
                 
                auto f = [this](cocos2d::EventCustom *event) //注冊c代碼形式的回調 這里用function做
                {
                    auto eventData = (dragonBones::EventData*)(event->getUserData());
                    auto type = (int) eventData->getType();
                    auto movementId = eventData->animationState->name;
                    auto lastState = eventData->armature->getAnimation()->getLastAnimationState();
                     
                    auto stack = cocos2d::LuaEngine::getInstance()->getLuaStack();
                    stack->pushObject(this"db.ArmatureNode");
                    stack->pushInt(type);
                    stack->pushString(movementId.c_str(), movementId.size());        
                    //通過LuaStack調用lua里的函數    最后一個參數設置參數個數
                    stack->executeFunctionByHandler(_movementHandler, 3);
                };
                 
                dispatcher->addCustomEventListener(dragonBones::EventData::COMPLETE, f);
            }
            void ArmatureNode::unregisterMovementEventHandler(void)
            {
                if (0 != _movementHandler)
                {
                    cocos2d::LuaEngine::getInstance()->removeScriptHandler(_movementHandler); //移除lua函數的綁定
                    _movementHandler = 0;
                }
            }
            • 提供Lua函數綁定到C的方法   

            上邊的這個函數直接用cocos里的genbinding.py 是無法正確生成Lua里可調用的接口的,需要手動編寫綁定方法.

            說這個得用到Cocos2d-x中提供的一個方法:toluafix_ref_function會把一個Lua棧中的方法轉成一個int,以便C++中調用。我會在最后面說這個

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            int tolua_db_DBCCArmature_registerMovementEventHandler(lua_State* tolua_S)
            {
                if (NULL == tolua_S)
                    return 0;
                int argc = 0;
                 
                dragonBones::ArmatureNode* self = nullptr;
                self = static_cast<dragonBones::ArmatureNode*>(tolua_tousertype(tolua_S,1,0)); //第一個參數 就是lua里的self
                 
                argc = lua_gettop(tolua_S) - 1;
                 
                if (1 == argc)
                {
                    //第二個參數,就是Lua里的function 這里要通過toluafix_ref_function這個函數映射成一個Int值
                    int handler = (toluafix_ref_function(tolua_S,2,0)); 
                    self->registerMovementEventHandler(handler);
                     
                    return 0;
                }
                return 0;
            }

             

            • 將綁定方法綁定到Lua環境里

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            int extends_ArmatureNode(lua_State* tolua_S)
            {
                lua_pushstring(tolua_S, "db.ArmatureNode");//之前db.ArmatureNode是通過腳本綁定在lua里。這里只做擴展
                lua_rawget(tolua_S, LUA_REGISTRYINDEX);
                if (lua_istable(tolua_S,-1))
                {
                    lua_pushstring(tolua_S,"registerMovementEventHandler");
                    lua_pushcfunction(tolua_S,tolua_db_DBCCArmature_registerMovementEventHandler);
                    lua_rawset(tolua_S,-3);
                }
                 
                lua_pop(tolua_S, 1);
                return 0;
            }
            • Lua里設置回調到C++

            1
            2
            3
            4
            5
            6
            7
            8
             local arm = db.ArmatureNode:create("Dragon")
                local animation = arm:getAnimation()
                animation:gotoAndPlay("walk")
                arm:registerMovementEventHandler(
                    function(...)
                        print(...) 
                    end
                )


            -測試

            打印回調輸出,測試通過 userdata 8 walk


            其他

            • toluafix_ref_function 以及 toluafix_get_function_by_refid

            這 兩個方法是相互對應的 toluafix_ref_function這個方法在注冊表上將一個lua的function與一個function_id生成映射 toluafix_get_function_by_refid 方法可以通過前一個方法生成的function_id來講綁定的lua function放到棧頂

            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            //
            TOLUA_API int toluafix_ref_function(lua_State* L, int lo, int def)
            {
                if (!lua_isfunction(L, lo)) return 0;
                s_function_ref_id++;                            //function_id 加1
                lua_pushstring(L, TOLUA_REFID_FUNCTION_MAPPING);//在注冊表上,存放luafunction 映射table 的key壓棧
                lua_rawget(L, LUA_REGISTRYINDEX);               //獲取方法映射表,放在棧頂
                lua_pushinteger(L, s_function_ref_id);          //function_id壓棧
                lua_pushvalue(L, lo);                           //lo有效處索引處是lua方法,lua方法拷貝,壓棧
             
             
                lua_rawset(L, -3);                        //生成映射 
                lua_pop(L, 1);                                              
                return s_function_ref_id;
            }
            TOLUA_API void toluafix_get_function_by_refid(lua_State* L, int refid)
            {
                lua_pushstring(L, TOLUA_REFID_FUNCTION_MAPPING);            //存放luafunction 映射table 的key壓棧
                lua_rawget(L, LUA_REGISTRYINDEX);                           //獲取方法映射表,放在棧頂
                lua_pushinteger(L, refid);                                  //function_id壓棧
                lua_rawget(L, -2);                                          //獲取到的luafunction 放到棧頂
                lua_remove(L, -2);                                          //
            }
            • executeFunctionByHandler

            executeFunctionByHandler 這個方法只是通過toluafix_get_function_by_refid 獲取到function然后通過lua_pcall 方法調用,代碼就不寫了。

            posted @ 2015-01-17 11:12 多彩人生 閱讀(2834) | 評論 (0)編輯 收藏

            僅列出標題  下一頁

            導航

            統計

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久婷婷五月综合97色直播| 国产精品欧美久久久天天影视| 99国产欧美精品久久久蜜芽 | 色偷偷久久一区二区三区| 久久国产一片免费观看| 品成人欧美大片久久国产欧美...| 国产91久久精品一区二区| 69久久精品无码一区二区| 久久久久99精品成人片试看| 亚洲AV无码1区2区久久| 久久人人爽爽爽人久久久| 无码国产69精品久久久久网站 | 无码人妻久久一区二区三区免费丨 | 久久精品国产99久久无毒不卡 | 欧美精品一本久久男人的天堂| 国产亚洲婷婷香蕉久久精品| 久久精品国产精品青草app| 情人伊人久久综合亚洲| 欧美日韩中文字幕久久久不卡 | 麻豆精品久久久久久久99蜜桃| 偷窥少妇久久久久久久久| 久久综合久久自在自线精品自| 999久久久免费精品国产| 麻豆精品久久久一区二区| 久久无码一区二区三区少妇 | 国产精品青草久久久久福利99| 久久久久国产精品嫩草影院| 国产aⅴ激情无码久久| 国产∨亚洲V天堂无码久久久| 久久精品18| 久久久久亚洲AV无码网站| 国产精品永久久久久久久久久| 无码国内精品久久综合88| 精品久久香蕉国产线看观看亚洲| 人妻少妇精品久久| 69SEX久久精品国产麻豆| 久久国产影院| 色综合色天天久久婷婷基地| 久久婷婷午色综合夜啪| 中文字幕成人精品久久不卡| 午夜精品久久久久久毛片|