- Debug Assertion Failed
- _BLOCK_TYPE_IS_VALID
- _CrtIsValidHeapPointer
24 5月 2013
[C/C++] 使用STL時,混用Debug & Release Mode的DLL or LIB可能會造成 Crash!
當你的Release mode的EXE,使用Debug mode的DLL,中間如果有操作(new/delete)STL的container,很容易讓AP crash,包括下列的error ...
[Python] 為Python2.5 unittest 加上setUpClass & tearDownClass 的功能
最近使用 Sikuli 替Project作AutoTest的功能,以Python的unittest為架構下去撰寫,發現有些綁手綁腳的地方,因為Sikuli是使用Jython 2.5,連帶的unittest也止於Python 2.5的版本。由於測試的項目眾多,需要撰寫多個TestCase,所以setUpClass與tearDownClass更顯得重要,可以為每個TestCase做pre-process與post-process。偏偏setUpClass與tearDownClass是在Python 2.7後才支援的,所以想在Sikuli裡套用的話,必須自己加一些Code才行了。
23 5月 2013
[C/C++] 取得LIB目前的DLL module path
如果寫了一個LIB or Cpp檔,讓多個DLL module include使用,該如果拿到目前DLL的module path?
GetModuleFileName() 參數hModule傳NULL的話,只能知道執行檔exe的路徑
要想知道自己在哪個DLL module的話,必須埋一些code才行
Reference :
GetModuleFileName() 參數hModule傳NULL的話,只能知道執行檔exe的路徑
要想知道自己在哪個DLL module的話,必須埋一些code才行
EXTERN_C IMAGE_DOS_HEADER __ImageBase
//...
WCHAR dll_path[MAX_PATH] = {0};
GetModuleFileNameW((HINSTANCE)&__ImageBase, dll_path, _MAX_PATH);
Reference :
- StackOverflow - Get Dll path at runtime
- MSDN - GetModuleFileName()
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中取得字串的內容。
在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 ,有一些選項可以選
最後就可以在指定的輸出路徑(ASM List Location)裡,找到各個檔案的*.asm or *.cod,打開來就可以研究一下裡面的assembly code了~
更多詳細的設定介紹 - MSDN - /Fa /FA
要打開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!
所以就有人嘗試在一開始將變數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()
使用說明,請參考前一篇文章。
下載連結(按右鍵另存新檔):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
使用說明,請參考前一篇文章。
下載連結(按右鍵另存新檔):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來得好多了。
有興趣的人可以下載來玩玩,更新了不少東西 :)
所以,才將 Project 轉移至 SourceForge,應該是之前有開過 Project 的關係,開新 Project 時也不需要審核,而且開新 Project 的步驟與介面也不像之前讓人退避三舍。上傳檔案的部分也有很大的進步(以前一定要在command line底下上傳才行),現在只要在網頁上東按西按就可以上傳了。重點是 Download 次數的統計實在比Google code來得好多了。
有興趣的人可以下載來玩玩,更新了不少東西 :)
訂閱:
文章 (Atom)
