青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

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 多彩人生 閱讀(654) | 評論 (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 多彩人生 閱讀(910) | 評論 (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 多彩人生 閱讀(510) | 評論 (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 多彩人生 閱讀(1588) | 評論 (0)編輯 收藏

2015年2月12日

cocos2dx lua protobuf

http://blog.csdn.net/weyson/article/details/17024325
http://m.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 多彩人生 閱讀(1571) | 評論 (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 多彩人生 閱讀(3427) | 評論 (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 多彩人生 閱讀(12622) | 評論 (0)編輯 收藏

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

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

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


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

posted @ 2015-02-05 18:30 多彩人生 閱讀(6887) | 評論 (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 多彩人生 閱讀(1956) | 評論 (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 多彩人生 閱讀(2861) | 評論 (0)編輯 收藏

僅列出標題  下一頁

導航

統計

常用鏈接

留言簿(3)

隨筆分類

隨筆檔案

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            在线亚洲欧美专区二区| 久久久天天操| 久久久久久久久久久久久9999| 亚洲免费视频成人| 日韩一级片网址| 亚洲欧美在线视频观看| 亚洲国产精品一区在线观看不卡| 伊人成人开心激情综合网| 欧美在线视频导航| 欧美大秀在线观看| 午夜一区二区三区在线观看| 最新国产精品拍自在线播放| 99在线|亚洲一区二区| 欧美激情欧美激情在线五月| 亚洲少妇在线| 久久夜色撩人精品| 欧美成人午夜| 国内精品视频久久| 久久久噜噜噜久久中文字免| 亚洲精品乱码久久久久久按摩观| 国产一区香蕉久久| 国产精品久久久久av| 欧美在线播放视频| 国产精品第三页| 久久久99国产精品免费| 久久久国产精品一区二区中文| 亚洲伦理在线观看| 久久不射电影网| 亚洲高清一二三区| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ入口 | 国产精品久久久久久久久久久久| 暖暖成人免费视频| 精品69视频一区二区三区| 亚洲国产精品专区久久| 洋洋av久久久久久久一区| 亚洲免费中文| 欧美国产日韩亚洲一区| 国产欧美日韩免费| 亚洲日本视频| 久久国产99| 黄色亚洲大片免费在线观看| 在线免费观看日韩欧美| 久久精品国产v日韩v亚洲| 午夜在线精品偷拍| 亚洲欧美日韩国产一区| 欧美日本网站| 老**午夜毛片一区二区三区| 亚洲午夜在线观看视频在线| 亚洲肉体裸体xxxx137| 久久免费视频一区| 亚洲国产va精品久久久不卡综合| 亚洲精品视频在线看| 欧美一区二视频| 一区二区动漫| 蜜臀va亚洲va欧美va天堂| 欧美亚洲一级片| 最近看过的日韩成人| 欧美在线视频免费观看| 伊人精品成人久久综合软件| 在线播放豆国产99亚洲| 欧美国产精品久久| 久久综合九色综合欧美就去吻| 国产日韩视频| 久久成人综合网| 久久视频一区| 欧美中文字幕不卡| 亚洲午夜精品久久久久久浪潮| 亚洲成人在线免费| 久久亚洲精品视频| 亚洲国产精品日韩| 欧美精品播放| 国产毛片一区| 一区二区三区精品视频| 国产伦精品一区二区三区免费迷 | 老司机精品视频网站| 国产亚洲欧美一区二区| 亚洲永久在线观看| 欧美在线观看www| 亚洲在线观看免费| 久久精品人人| 欧美人与性动交α欧美精品济南到| 亚洲视频视频在线| 国产精品婷婷| 久久精品亚洲| 欧美国产日韩一二三区| 亚洲乱码国产乱码精品精天堂 | 亚洲国产成人久久综合| 亚洲三级电影全部在线观看高清| 亚洲美女一区| 亚洲一区二区欧美日韩| 欧美人成在线| 美女91精品| 一区免费观看| 亚洲男女自偷自拍| 99视频精品全国免费| 国产精品一香蕉国产线看观看| 亚洲美女在线视频| 亚洲欧美日韩成人高清在线一区| 另类天堂av| 亚洲欧美激情精品一区二区| 国产精品免费久久久久久| 免播放器亚洲一区| 日韩写真在线| 亚洲电影激情视频网站| 欧美日韩在线播放| 一本色道久久综合亚洲91| 久久久久中文| 亚洲韩国青草视频| 欧美理论在线播放| 小辣椒精品导航| 亚洲视频视频在线| 欧美高清视频一区二区| 久久婷婷影院| 亚洲国产精品123| 国产日韩在线看片| 久久亚洲不卡| 99精品欧美一区二区三区综合在线 | 蜜臀av性久久久久蜜臀aⅴ四虎| 激情综合电影网| 久久精品一本| 在线精品视频免费观看| 久久精品在线免费观看| 嫩草成人www欧美| 欧美jjzz| 国产午夜精品麻豆| aⅴ色国产欧美| 91久久精品国产91久久性色| 国产一区二区av| 亚洲国产另类久久精品| 欧美激情亚洲国产| 99视频精品在线| 久久国产福利国产秒拍| 裸体歌舞表演一区二区| 欧美日韩性视频在线| 91久久久国产精品| 国产精品综合久久久| 久久久久久久一区二区三区| 亚洲你懂的在线视频| 欧美成年网站| 国产啪精品视频| 亚洲免费综合| 亚洲欧美在线视频观看| 亚洲人成人一区二区在线观看 | 蜜乳av另类精品一区二区| 亚洲欧美一区二区激情| 欧美一区二区三区男人的天堂 | 国产精品你懂的在线| 亚洲天堂成人在线观看| 亚洲欧美日韩高清| 亚洲视频日本| 久久精品五月婷婷| 老鸭窝亚洲一区二区三区| 性久久久久久久| 欧美激情麻豆| 国产亚洲精品福利| 久久综合久久美利坚合众国| 欧美色欧美亚洲另类七区| 男人的天堂成人在线| 欧美视频日韩| 久久精品国产v日韩v亚洲 | 国产精品99久久久久久宅男 | 亚洲视频免费在线观看| 91久久午夜| 夜夜夜久久久| 99re6这里只有精品视频在线观看| 亚洲第一精品福利| 亚洲国产中文字幕在线观看| 亚洲精品久久久蜜桃| 国产午夜精品久久| 欧美日韩国产系列| 久久精品视频一| 欧美国产日本韩| 午夜久久电影网| 午夜综合激情| 国产欧美日韩一区二区三区| 夜夜嗨一区二区| 久久国产精品网站| 久久精品视频99| 久久一区激情| 久久精品成人| 欧美激情视频一区二区三区不卡| 午夜天堂精品久久久久| 亚洲第一区色| 亚洲免费观看视频| 免费成人美女女| 99精品国产在热久久| 亚洲麻豆国产自偷在线| 一本色道久久综合亚洲二区三区| 亚洲日本中文| 性欧美大战久久久久久久久| 欧美亚洲免费| 国产欧美日韩综合一区在线播放| 亚洲男人的天堂在线aⅴ视频| 久久精品视频一| 欧美日韩激情网| 久久这里只有| 国产精品私房写真福利视频| 久久人人看视频| 一本大道久久a久久综合婷婷| 久久野战av|