強大的Eclipse開發社群,提供了PHP的debug功能 - PHP Development Tool (PDT) PlugIn,可以執行並下中斷點,對PHP開發者而言著實是一大福音!
PDT套件可以視為是debug的client端,而server端的話,就需要在PHP安裝extension才行,目前PDT支援的包括(1)Zend Debugger (2)XDebug,以下就介紹PDT以Zend Debugger的方式進行debug ...
25 6月 2013
06 6月 2013
[Sikuli] Compile Sikuli-IDE source code in Eclipse
Sikuli是新堀起的Programming Language,以圖象化的方式來coding真的是一大圖破創新的想法。重點是...還是台灣人做的呢!Sikuli是Open Source的,所以有不少人為這個Project供獻一己之力,最近公司的Project用它來做AutoTest,整個很給力,決定來compile它的source code來玩看看,雖然說很久沒寫Java了.... XD
Sikuli的Project切成兩部分,一個是整個核心的Sikuli-API是以Java、C++為主,另一個是開發平台的Sikuli-IDE是純Java的Project,由於整個核心API切出來成一個單獨的Project,所以如果想自己寫一個Java的程式直接使用Sikuli-API是可行的!詳見:How to use Sikuli Script in your Java Program?
也由於Sikuli API模組化的關係,目前Sikuli Script語法是Python,以後可能還會陸續支援其他語言吧。
Sikuli的Project切成兩部分,一個是整個核心的Sikuli-API是以Java、C++為主,另一個是開發平台的Sikuli-IDE是純Java的Project,由於整個核心API切出來成一個單獨的Project,所以如果想自己寫一個Java的程式直接使用Sikuli-API是可行的!詳見:How to use Sikuli Script in your Java Program?
也由於Sikuli API模組化的關係,目前Sikuli Script語法是Python,以後可能還會陸續支援其他語言吧。
25 5月 2013
[C/C++] 研究long long * float overflow 可能導致的誤差
最近看bug看到一個奇怪的現象,在64bit的AP執行時,long long * float會有誤差出現,但是32bit的AP卻沒有這樣子的問題出現,直覺上不是應該32bit的AP比較會有問題嗎!?
先來看一下 long long 跟 float ,long long的size是8個byte,float的size是4個byte
long long * float,compiler會將結果存到float的temp變數裡,此時誤差就可能會出現了,但是這個誤差是「有條件」地出現,並不是任何long long的數字乘上float都會產生誤差的
以一個簡單的程式來驗證是否會產生誤差
先來看一下 long long 跟 float ,long long的size是8個byte,float的size是4個byte
long long * float,compiler會將結果存到float的temp變數裡,此時誤差就可能會出現了,但是這個誤差是「有條件」地出現,並不是任何long long的數字乘上float都會產生誤差的
以一個簡單的程式來驗證是否會產生誤差
bool check_longlong(long long v1)
{
float f = 1.0f;
long long v2 = long long( v1 * f );
printf("ori value=%lld, new value=%lld, ori==new=%d", v1, v2, v1==v2);
return v1==v2;
}
int _tmain(int argc, _TCHAR* argv[])
{
check_longlong(0xF0000000000);//true - OK
check_longlong(0x0FFFFFFFFFF);//false - Error!
check_longlong(0x0FFFFFF);//true - OK
check_longlong(0x1FFFFFF);//false - Error!
return 0;
}
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 ...
- Debug Assertion Failed
- _BLOCK_TYPE_IS_VALID
- _CrtIsValidHeapPointer
[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轉換出來的字串就有可能會變成亂碼了。
訂閱:
文章 (Atom)
