22 3月 2013

[C/C++] General pointer type for support x86 & x64

一個pointer的size在x86跟x64的環境裡是不一樣大的

  • x86's pointer size = 4 bytes
  • x64's pointer size = 8 bytes
如果你在程式中用int or long去儲存一個pointer的話,可能在compile成x86可以work,但是compile成x64執行的話,可能就會exception了

所以建議是用標準的 uintptr_t / intptr_t 去儲存pointer,uintptr_t在copmpile成x86時的size是4 bytes,x64是8 bytes,它在C++11時才被列入標準,但在大部分的C++03的compiler已經支援了

include header : <cstdint>

Reference : 

10 3月 2013

[wxWidgets] function 傳入wxString的不定參數

在C/C++裡有不定參數的功能,讓一個function可以傳入不固定數目的參數,在function裡,透過va_list, va_arg() 把參數一個個抓出來。

在wxWidgets裡,擁有特有的字串類別wxString,用法跟std::string, std::wstring稍稍不同(多了很多API)。

std::string/std::wstring可以透過c_str()取得的內部字串buffer (char*/wchar_t*)
wxString也可以透過c_str()取得內部字串的buffer,型別是wxChar

wxChar是wxWidgets定義的,會根據compile定義的wxUSE_UNICODE(是否為unicode的build)分別對應到unicode : wchar_t, ansi : char

由於wxString是wxWidgets包裝起來的class,若將它傳進function當不定參數之一,va_arg()將無法取得wxString正確的字串內容,所以如果要將wxString的字串傳入不定參數的function中,需以c_str()傳入wxChar*字串的pointer,才能在function中取得字串的內容。

// the parameter must be wxChar*
// -> please convert wxString by c_str() before push it
//    _T("") would be convert to wxChar*
// Ex: wxString s = _T("Falldog");
//     ComposeContent(2, s.c_str(), _T("'s blogger"));
wxString ComposeString(int count, ...)
{
    wxString res;
    va_list vl;
    va_start(vl, count);
    for(int i=0 ; i<count ; ++i)
        res += va_arg(vl,wxChar*);
    va_end(vl);
    return res;
}

30 8月 2012

[Code::Blocks] Compile Code::Blocks source code in Windows

Code::Blocks是一款出色的跨平台IDE,是用跨平台的語言wxWidgets所寫的,由於wxWidgets並不像Java一樣,有Virtual Machine,是可以build成原生的執行檔執行的,所以執行的速度會快很多。由於最近想寫看看Code::Blocks的PlugIn,所以就試著build CB的source code看看,用CB來build CB倒是挺有趣的。

23 8月 2012

[VisualStudio] Generate Assembly result file

VisualStudio在compile檔案過後,預設是不會產生assembly file的,但是有時候會想看看compile過後assembly code長怎麼樣,當project的Optimization有enabled的話,一樣的code在不同的Optimization level會有不一樣的結果,這就是VC對code優化處理。

要打開assember output的話,先進入Project Property Page(在project上點右鍵,選propertys)
以VS2008為例,在 Configuration Properties | C/C++ | Output Files
選擇 Assembler Output ,有一些選項可以選

  • Assembly-Only   (輸出.asm檔)
  • Assembly, Machine Code and Source (輸出.cod檔)
  • Assembly With Machine Code  (輸出.cod檔)
  • Assembly With Source Code  (輸出.asm檔)
可以選擇最詳細的Assembly, Machine Code and Source來看



最後就可以在指定的輸出路徑(ASM List Location)裡,找到各個檔案的*.asm or *.cod,打開來就可以研究一下裡面的assembly code了~

更多詳細的設定介紹 - MSDN - /Fa /FA

16 3月 2012

[Win32] Save Bitmap

Save Gdiplus::Bitmap
HRESULT GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
    /*
    format support : 
        "image/png"
        "image/bmp"
        "image/gif"
        "image/jpeg"
        "image/tiff"
    */
    UINT  num  = 0;  // number of image encoders
    UINT  size = 0;  // size of the image encoder array in bytes

    GetImageEncodersSize(&num, &size);
    if(size == 0)
        return E_FAIL;  // Failure

    ImageCodecInfo* pImageCodecInfo = NULL;
    pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
    if(pImageCodecInfo == NULL)
        return E_FAIL;  // Failure
    GetImageEncoders(num, size, pImageCodecInfo);
    for(UINT j = 0; j < num; ++j)
    {
        if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
        {
            *pClsid = pImageCodecInfo[j].Clsid;
            free(pImageCodecInfo);
            return S_OK;  // Success
        }
    }
    free(pImageCodecInfo);
    return E_FAIL;
}

void SaveBitmap(Bitmap* bitmap)
{
    // Get the CLSID of the JPEG encoder.
    CLSID clsid;
    GetEncoderClsid(L"image/jpeg", &clsid);
    
    bitmap.Save(L"C:\\test.jpg", &clsid, NULL);
}

04 8月 2011

[Python] Lazy initialization

在寫大型的Project時,應該都會遇到一種痛,就是AP開起來的速度"操級慢",很多人習慣在一開始就把一些用不到的變數initial起來,不但影響到AP launch的速度,也會讓memory吃得肥茲茲的。

所以就有人嘗試在一開始將變數initial成None,等到要用時再判斷是不是None,是的話再真正的initial這個變數。

不過這種作法,可能會讓code變得稍微複雜一點,參考一下別人的作法,其實有更好的方法來實作這種Lazy Initialization,就是用到Python的decorator+property!

12 4月 2011

[Python] 取得Python object的reference count

在Python的世界裡,每個變數都是一個object,而且每個object會有一個reference count去記錄被reference幾次,一但這個值變0時,這個object才會真正被delete掉。

[Python] 實作一個PriorityQueue 與 有pause, resume 功能的PriorityTaskThread

由於project是用Python2.5,要用到PriorityQueue,但是Python2.6以後才支援PriorityQueue,所以就想說寫個來試試。主要是改寫自Python原有的Queue class,繼承了原有的access blocking的feature,將原本的put改用insert與append,讓有相同priority的task能有先後之分。

07 4月 2011

[Python] Hook stdout後 print會出現 UnicodeDecodeError

在Python裡,字串的表達方式分為兩種,一種是常見的ansi string:"abc",另一種則是unicode:u"abc",而OS在秀出文字到window上時,其實都會轉換到使用者設定的code page後才秀出來的。簡單來說,繁體中文有一個對應的code page(cp950),簡體中文也有個對應的code page(cp936),如果一個unicode的字串參考錯誤的code page轉換出來的字串就有可能會變成亂碼了。

22 12月 2010

[emomeDDSMS] 下載emome上的備份簡訊 更新0.73

應觀眾要求,新增功能,輸出傳送簡訊的號碼與通訊錄的暱稱。
下載連結(按右鍵另存新檔):emomeDDSMS 0.73 (2010/12/22)
Change Log:
1. Add output phone number and nick name function - GetPhoneBook() and ConvertPhonelist()

使用說明,請參考前一篇文章。

28 9月 2010

[emomeDDSMS] 下載emome上的備份簡訊 更新0.72

因應emome網頁些許的更新與問題,emomeDDSMS也要稍作修改。
下載連結(按右鍵另存新檔):emomeDDSMS 0.72 (2010/9/28)
Change Log:
1. emome browse sms page changed, 'from' action changed to 'POST', modify related url actions.
2. Add ResetPage() mechanism for emome website issue, sometimes can't browse normal
3. Add description, suggest to download file to D disk

使用說明,請參考前一篇文章。

12 5月 2010

[SudokuBoxer] Project 轉移至 SourceForge

一開始將 Project 放在Google code,連線至SVN的速度還不錯,介面操作很陽春,但是也很方便。不過使用了一陣子後,發現放在上面供人下載的檔案,下載次數有著砂鍋大的問題,不管下載幾次,次數都不會增加,這樣子的結果實在令人傷心…到Google code的論壇發問,才知道原來這個 issue 已經 create 出來很久了,早在2009/12時就已經存在了,但是到現在還沒修好,這效率著實令人吃驚。

所以,才將 Project 轉移至 SourceForge,應該是之前有開過 Project 的關係,開新 Project 時也不需要審核,而且開新 Project 的步驟與介面也不像之前讓人退避三舍。上傳檔案的部分也有很大的進步(以前一定要在command line底下上傳才行),現在只要在網頁上東按西按就可以上傳了。重點是 Download 次數的統計實在比Google code來得好多了。

有興趣的人可以下載來玩玩,更新了不少東西  :)


25 3月 2010

[SudokuBoxer] wxPython 實作Sudoku GUI Game

前一陣子利用空閒時間練習了一下wxPython,順便寫了一個Sudoku的小遊戲,想說完成的話,可以給我媽玩一下。

目前的功能還很陽春,不過至少題目的難易度滿正確的,在產生正確的題目上費了不少功夫,曾經嘗試過連到某Sudoku網頁去解析題目網頁的html語法,然後再儲存到DB裡,可是這招實在是太sucks了,抓不到50題,就被擋IP了 XD (看來是sleep的間隔時間不夠長.... ) 後來還找了一些tool來產生題庫,但是效果都不盡理想,不是題目有問題,就是題目難易度不均。

後來終於找到一個 Sudoku 產生題庫的 tool,跟一個可以幫題目打分數的 tool。雙管其下的結果還算讓人滿意。


Sudoku Importer - 以挖洞法產生sudoku題庫,所以必須餵入題目挖洞的template
Sudoku Explainer - 一個強大的Java GUI Sudoku軟體,可以教你怎麼一步步解題,以及解題所需要的技巧,最重要的是可以餵給它題目,然後產生該sudoku的難度分數以及解題所需要的技巧。
改天再寫一篇介紹怎麼用這兩個 tool 吧。


SudokuBoxer遊戲畫面

SudokuBoxer是用wxPython實作的,可惜的就是執行檔大了一點, 壓縮完後竟然還要5MB,沒壓縮也要15MB,真是誇張。

這也是我第一次用wxPython,第一次自己動手用 gettext 作 Multi-Language,程式還有很多功能沒完成,不過應該是不會輕易當掉啦,呵。想說弄到一個段落就放上來Share給大家一下。Python上手後,真的是快速開發的好物啊!

可惜 wxPython(wxWidgets) 在繪圖上的功能過於陽春,連 Texture 之間的 Alpha Blending 功能都沒有,不過wxWidgets可以貼OpenGL的Canvas上去,應該可以補足這一塊,但還要花時間學OpenGL就是了,大學學過都還給老師了....

22 3月 2010

[emomeDDSMS] 下載emome上的備份簡訊 更新0.71

因應emome網頁些許的更新,emomeDDSMS也要稍作修改。
下載連結:emomeDDSMS 0.71 (2010/3/21)
Change Log:
1. Modify login.js path in Login()
2. Modify @name to @user_name, because unknow Chickenfoot issue to use parameter @name.

使用說明,請參考前一篇文章。

26 2月 2010

[wxPython] 實作多國語言MUI by GetText

wxPython提供了方便的支援多國語言API,結合GNU GetText project,使用上很是方便。
由GetText parse 檔案後,建出PO檔然後轉成MO檔,就可以給wxPython讀取使用。