backtrace(bt):顯示程式目前的stack狀態,用於檢查dump core很方便。
frame #:配合backtrace的結果,選擇要跳到的stack #,就可以檢查某個stack的狀態。
在多個source files裡面跳到其他file:list filename:1,用來跳到filename這個檔案的第一行。
用 list 也可以跳到某個檔案的某個function,list filename:function。
參考資料 :
http://www.study-area.org/cyril/opentools/opentools/x1253.html
2008年6月27日 星期五
[+/-] |
gdb的一些常用指令 |
[+/-] |
Google App Engine |
如何利用Google App Engine來建立自己的Web Service:
http://blog.pixnet.net/jacklin0508/post/16272390
Google App Engine的 Tutorial:
http://code.google.com/appengine/docs/gettingstarted/
jQuery:Javascript Library
http://jquery.com/
django:Python Web Framework
http://www.djangoproject.com/
http://www.openfoundry.org/index.php?option=com_content&Itemid=144&id=1330&lang=en&task=view
參考資料 :
http://blog.pixnet.net/jacklin0508/post/16272390
2008年6月24日 星期二
[+/-] |
[Python] 字串處理, 檔案讀取, 系統參數, Trace目錄 |
Python 字串處理:
return value
切token : str.split(delimiter) list
找字尾 : str.endswith(endString) bool (有沒有找到)
找字首: str.startswith(startString) bool (有沒有找到)
找子字串 : str.find(subString) 子字串的開頭位址
去空白 : str.strip() string
Regular expression:
re.search(regex, subject)
re.match(regex, subject)
re.findall(regex, subject)
re.finditer(regex, subject)
re.sub(regex, replacement, subject)
re.split(regex, subject)
re.complie(regex, subject)
檔案處理:
fp = open(file, "r") #讀檔
fileString = fp.read() #把整個檔案讀入buffer
fileLines = fp.readlines() #把整個檔案以一行一行形式讀入list
執行參數:
import sys
sys.argv #參數個數
sys.argv[1] #第1個參數
Trace 目錄:
import os, sys
from stat import *
def walktree(top, callback):
'''recursively descend the directory tree rooted at top,
calling the callback function for each regular file'''
for f in os.listdir(top):
pathname = os.path.join(top, f)
mode = os.stat(pathname)[ST_MODE]
if S_ISDIR(mode):
# It's a directory, recurse into it
walktree(pathname, callback)
elif S_ISREG(mode):
# It's a file, call the callback function
callback(pathname)
else:
# Unknown file type, print a message
print 'Skipping %s' % pathname
def visitfile(file):
print 'visiting', file
if __name__ == '__main__':
walktree(sys.argv[1], visitfile)
參考資料:
Python's re Module
stat -- Interpreting stat() results
Common string operations
Python Library Reference
2008年6月19日 星期四
[+/-] |
Firefox 3.0 |
最新版本的Firefox比起之前的版本有以下的感覺:
1. 速度有變快
2. 附加元件管理員變的比較好
3. 書籤組織功能加強
Firefox一些好用的Plugins:
1. google toolbar:整合google的工具在 firefox 的 toolbar 上面。
2. GMark:專門使用 google 書籤 的 plugin,介面跟編輯有比原本 google toolbar 上面的好用,重點在於使用 Ubuntu 不會讓書籤無法下載。
3. RefControl:可以對某個網站指定要送的 Referer 是什麼,對於那種不讓站外連圖片的網站(無X),可以達到破解的效果。
4. Clipmarks:可以把一個網頁上的東西切成一塊一塊,並且選擇你想要剪下的部分,傳送到 Clipmarks 的網站。可以用來剪貼網路上面的資訊。
參考資料 :
Mozilla Taiwan 正體中文 - http://www.moztw.org/
2008年6月17日 星期二
[+/-] |
wxPython中有興趣的widget |
顯示進度 (wx.Gauge):wxPython in Action(五十六)
顯示進度 Dialog (wx.ProgressDialog):wxPython in Action(七十七)
分割視窗 (wx.SplitterWindow) : wx.SplitterWindow
多重版面 (wx.Notebook):wx.Notebook
Wizard (安裝導覽, 教學導覽) (wx.Wizard):wxPython in Action(八十一)
參考資料 :
The wxPython tutorial - http://zetcode.com/wxpython/
wxPyhthon In Action - http://www.pythontik.com/blog/default.asp
2008年6月16日 星期一
[+/-] |
C : 非固定參數function |
有很多格式化的function,像是 printf,scanf 之類,由於格式不固定,造成後面接的參數個數也不一定。這時候就要用到非固定參數 function 的技巧了。
#include <stdarg>
void print(char *fmt, ...)
{
//宣告一個多參數變數
va_list ap;
//重組的格式
char *nFmt;
//取得多參數變數的初始化
va_start(ap, fmt);
//重組字串的格式 (asprintf 會自動幫buf allocate記憶體)
asprintf(&nFmt, "%s\n", fmt);
//輸出結果到stdout
vfprintf(stdout, nFmt, ap);
//釋放asprintf 自動 allocate的記憶體
free(nFmt);
}
這個function print所做的事情就是把原本要印出的字串格式重組,
最後在後面加個"\n"。
參考資料 :
man va_start
2008年6月13日 星期五
[+/-] |
libpq : include 和 library 的設定 |
在 shell 下輸入:pg_config --help ,會出現很多 option 可以選擇。
其中 --includedir 是 libpq C header的位置
而 --libdir 是 library的位置
在compile時,把 gcc -I (include dir) 和 -L (library dir) 的 path 設定正確,這樣才不會出現 undeclare 或是 undefined reference 的錯誤產生
參考資料 :
http://www.freebsd.org.hk/html/postgresql/libpq-chapter.htm
[+/-] |
libpq : 存取PostgreSQL的C API |
我們寫的程式透過 libpq 的 api 可以間接存取 PostgreSQL 裡面的資料。
要對 PostgreSQL 執行一個 SQL Command 步驟分成以下幾步:
1. 連上 PostgreSQL 上的 DB ( conn = PQconnectdb(connStr) )
2. 檢查 PQconnectdb 回傳的狀態 ( PQstatus(conn) == CONNECTION_OK )
3. 執行 SQL Command ( res = PQexec(conn, SQLCmd) )
4. 檢查回傳的 res 是否正常 ( PQresultStatus(res) == PGRES_TUPLES_OK )
5. 取出 res 裡的資料 ( for (i = 0; i < PQntuples(res); i++)
{
PQgetvalue(res, i, 0)
}
)
6. 清除資料 ( PQclear(res) )
7. 和資料庫斷線 (PQfinish(conn))
參考資料 :
C Language Interface (LIBPQ) - http://www.postgresql.org/files/documentation/books/aw_pgsql/node147.html
2008年6月12日 星期四
[+/-] |
C++ : 如何把class member function當成function pointer傳入 |
將 member function 宣告成 static 就可以傳入。
可是 static member function 不能呼叫this pointer,這樣就失去呼叫 member function 的意義了。解決方法是把在呼叫時,把物件的指標傳入。但是呼叫別人的function時,不能改變參數,所以必須建立一個 global variable 或是 static member variable ,在產生物件的同時,把這個變數設定成物件的 reference ,這樣一來呼叫 static member function 時,就可以利用這個 variable 來呼叫物件的其他東西。
class Obj
{
public:
static void *self; //指向自己的pointer
Obj()
{
Obj::self = this; //指向自己
}
static void WrapperFun() //wrapper function
{
Obj::self->Fun(); //真正要呼叫的member function
}
void Fun()
{
//...
}
};
呼叫時:
some_function(WrapperFun);
這樣就可以達到呼叫我們要呼叫的non-static member function的效果了。
參考資料 :
Executing an Object's Member Function in a Separate Thread - http://gethelp.devx.com/techtips/cpp_pro/10min/10min0800.asp
How to use SetTimer() with callback to a non-static member function - http://www.cppblog.com/leo-chen/archive/2007/05/16/24186.html
2008年6月10日 星期二
[+/-] |
vim我會用的指令 |
在unix上編輯東西當然少不了vim。雖然沒有視窗的直覺化,但是透過簡潔的指令,我們更能專注於我們要編輯的內容,而不是隨意的剪剪貼貼。
下面介紹編輯檔案好用的多檔編輯:
1. 開啟檔案時可以 vim file1 file2 ... 一次開啟好多檔案。
2. 輸入 :files 會出現檔案名稱以及檔案編號。
3. :n 可以編輯下一個檔案
4. :N 可以編輯上一個檔案
5. :b# #代表輸入 :files 以後出現的檔案前面的編號,用來跳到編號為#的檔案編輯。
6. 按 Ctrl + ^ ,可以切換目前檔案以及前一個編輯的檔案。
透過這些指令在多個檔案的編輯也可以很簡單達成。
其他詳細的 vim 介紹,可以到鳥哥的 Linux 私房菜 - vi 文書處理器或是大家來學 Vim 一個歷久彌新的編輯器找到詳細內容。
參考資料 :
鳥哥的 Linux 私房菜 - vi 文書處理器 - http://linux.vbird.org/linux_basic/0310vi.php
大家來學 Vim 一個歷久彌新的編輯器 - http://edt1023.sayya.org/vim/
2008年6月9日 星期一
[+/-] |
Unix Socket程式範例 |
Server :
建立socket -> 設定local address -> 將socket bind在local port上 -> listen client socket -> 當有socket連線時accept client socket -> recv/send
Client :
建立socket -> 設定remote(server) address -> connect遠端server -> 當connect成功之後 -> recv/send
範例請見參考資料。
參考資料 :
http://www.pcs.cnu.edu/~dgame/sockets/sockets.html
2008年6月5日 星期四
[+/-] |
read function 設定Non-Blocking I/O的方式 |
利用 fcntl 或是 ioctl 來設定 Non-Blocking I/O,讓 read function 不會被 Block住:
#include <fcntl.h> //fcntl的header
#include <sys/ioctl.h> //ioctl的header
...
int flag;
//用fcntl設定Non-Blocking I/O
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
//用ioctl設定Non-Blocking I/O
ioctl(STDIN_FILENO, FIONBIO, &flag);
fcntl的完整用法是先用F_GETFL取得flags,在把flags和要改變的flag進行&、|,最後在用F_SETFL把flags設定回去。
int flags;
//取得flags
if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
{
//進行錯誤處理
}
//加入non-blocking I/O的flag
flags |= O_NONBLOCK;
//設定flags
if ((flags = fcntl(fd, F_SETFL, flags)) == -1)
{
//進行錯誤處理
}
參考資料 :
Advanced Programming in the Unix Environment
[+/-] |
C程式在Unix下取得時間 |
在Unix下取得時間的方法如下:
1. time取得系統時間 (time_t)
2. 把 time_t 的時間轉換成 struct tm 格式的時間:localtime (取得在地時間),gmtime (取得格林威治時間)
3. 用印出 struct tm 的函式來把時間用想要的格式印出:asctime (預設的格式),strftime (可以自訂輸出格式)
以上就是轉換流程,如果要把 struct tm 轉回 time_t 則是用 mktime 。
#include <time.h>
...
time_t t;
struct tm *tm_t;
//取得系統時間
t = time(NULL);
//把系統時間轉成當地時間
tm_t = localtime(&t);
//印出時間
printf("%s", asctime(tm_t));
//把strcut tm轉成time_t
//t = mktime(tm_t);
參考資料 :
http://www.cs.nctu.edu.tw/~yslin/library/linuxc/function/04.html
Standard C Date & Time - http://www.cppreference.com/stddate/index.html
[+/-] |
關於匈牙利命名法的討論 |
進入公司後看到的 Code 大部分都是用 匈牙利命名法 這個規則命名的。一開始的時候看到變數前面有m_、n、sz、lp等等一連串的怪怪 prefix ,讓本來就不懂的程式碼看起來更加痛苦。但是慢慢的了解了這個規則以後,發現到看別人的程式,如果有這樣的命名其實還不錯。
像是大家常常喜歡執行一個 Member Function 來改變 Member Variables ,當然程式如果是自己寫的很容易就知道那些 Member Variables 被修改了。但是這可苦了看你程式的人,尤其是沒有寫 Function 註解的時候。往往一個 Member Function 做完了以後,沒有回傳值,根本不曉得它到底做了些什麼。
所以說 匈牙利命名法 真的這麼好嗎?
在網路上搜尋的結果,發現到當然也是有人覺得它不錯,但是下面這篇討論,指出了它受到質疑的缺點 : 匈牙利命名法討論的文章。
當然缺點裡面有誇大的地方,不見得所有的地方都是不好的。Making Wrong Code Look Wrong(中文)這篇文章,就指出了 匈牙利命名法 最初的原意。它的用途在於知道變數的種類(Kind),而不是型態(Type)。知道變數的種類(Kind)就能幫助看程式的人,從變數本身看出程式碼的錯誤。文章裡面也有舉了一個例子來說明。
所以當你使用 匈牙利命名法 來命名的時候,可以想想看這樣的做法是否可以幫助你了解程式,以及對程式的除錯是否有幫助。不然這樣的做法會讓程式的變數看起來眼花撩亂,可能跟你原本想要的結果大有不同 (最終目的是幫助程式的閱讀)。
參考資料 :發佈文章
Making Wrong Code Look Wrong(英文) - http://www.joelonsoftware.com/articles/Wrong.html
Making Wrong Code Look Wrong(中文) - http://chinesetrad.joelonsoftware.com/Articles/Wrong.html
匈牙利命名法討論的文章 - http://tsjeremy.spaces.live.com/blog/cns!BD4EB7F462639B16!1346.entry
[+/-] |
程式碼的風格 (Coding Style) |
寫了這麼久的程式,但是對 Coding Style 卻沒有一個很明確的規範。常常變數寫怎麼取就怎麼取,因為以前寫的程式都是為了單一的目的 (通常是交作業) 而寫的。在進公司接了別人的程式以後,就深深的覺得好的 Coding Style 真的很重要。
像是變數的命名方式,如果在取名的時候不在 Class Member 前面加上 m_ 的前置符號,在看新的程式就會很難判別一個變數的範圍。往往在一個 Function 執行完以後,還不知道這個 Function到底做了些什麼事情,因為不曉得哪些變數是 Class Member 。帶大量參數的縮排也是一樣,好的縮排可以幫助我們很快的了解這個 Function 裡面的參數意義。當然我覺得最重要的還是在 Function 或是 Class 的前面可以加上註解會是更好的,常常你的小小註解,可以省下其他人 (更常是自己)很多時間。
下面這三份資料是介紹一些 Coding Style 的方法,分別是 C , C++ , C# 。但是我想基本概念都是差不多的。
C♯ Coding Style Guide
C++ Programming Style Guidelines
Recommended C Style and Coding Standards
希望大家的程式碼都是能容易閱讀的,讓看別人的程式碼變成是程式技術增進的快速方法,而不是一個痛苦的工作。
參考資料 :
C♯ Coding Style Guide - http://www.icsharpcode.net/TechNotes/SharpDevelopCodingStyle03.pdf
C++ Programming Style Guidelines - http://geosoft.no/development/cppstyle.html
Recommended C Style and Coding Standards - http://www.psgd.org/paul/docs/cstyle/cstyle.htm
2008年6月4日 星期三
[+/-] |
Bsd裡面的ls顏色設定 |
設定的流程如下 :
1. 設定TERM這個環境變數為xterm-color (在openbsd裡面為xterm-color)
2. 確認 ls 產生顏色的方法。是用 ls --color 來設定,還是用 colorls -G 。
3. 在 .profile 檔裡面 (ksh) ,設定 alias 方便使用。例如:alias ls = 'colorls -G'
4. 更改顏色的設定,在bsd裡面是用LSCOLORS這個變數的設定
DIR=Dx
SYM_LINK=Gx
SOCKET=Fx
PIPE=dx
EXE=Cx
BLOCK_SP=Dx
CHAR_SP=Dx
EXE_SUID=hb
EXE_GUID=ad
DIR_STICKY=Ex
DIR_WO_STICKY=Ex
export LSCOLORS="$DIR$SYM_LINK$SOCKET$PIPE$EXE$BLOCK_SP$CHAR_SP
$EXE_SUID$EXE_GUID$DIR_STICKY$DIR_WO_STICKY"
上面的LSCOLORS後面的內容為一行。
詳細的介紹可以參考ls 顏色設定(in Bash shell)。
參考資料 :
ls 顏色設定(in Bash shell) - http://plog.longwin.com.tw/post/1/408
[+/-] |
使用CAsyncSocket碰到的問題 : Create |
在用MFC寫網路程式的時候,會用CAsyncSocket來產生出自己的非同步Socket Class。用CAsyncSocket建立連線的時候,Client端只要呼叫Create和Connect這兩個Function就好了,不需要像純粹的Socket一堆設定動作。
而這些繁雜的設定都被包在Create裡面了,這也是我這次碰到的問題。
那Create裡面到底做了些什麼?
1. 呼叫CAsyncSocket的Socket函式
1.1 Socket函式裡面會先檢查m_hSocket是否被清成INVALID_SOCKET
1.2 呼叫利用socket函式產生新的m_hSocket
2. 如果呼叫Socket函式成功,接下來呼叫Bind函式,在Bind函式裡面會設定一些Socket相關資訊,然後進行Bind的動作
3. 最後就是成功Create,然後執行Connect到Server。
而我產生錯誤的地方就在 1.1 的部分,因為我的程式可能因為遠端Server無法連線而造成Connect失敗,在Connect失敗以後我沒有呼叫Close來清除m_hSocket的資源,並且將m_hSocket給設定成INVALID_SOCKET,因此在呼叫Create的時候就會產生出ASSERT的錯誤訊息。
所以對於使用的函式庫的function,如果能多了解裡面程式碼實際的內容的話,就能避免掉一些因為和函式庫設計邏輯不同而產生的錯誤。
參考資料 :
MSDN
2008年6月3日 星期二
[+/-] |
libevent : event-driven的IO函式庫 |
網路IO最麻煩的就是多個連線的處理, 要用fork, thread, 或是select, poll之類的方式來處理.
libevent提供了很方便的方式來處理多個連線的問題. 你只要註冊某個file descriptor (socket), 在發生read event時做什麼動作, write event時做什麼動作就可以了. libevent會根據你所在的平台提供的解決方式來幫你選擇.
void callback(int fd, short event, void *arg); //callback function的prototype
struct event ev;
...
event_init(); //初始化
...
//設定fd在發生EV_READ時, 呼叫callback這個function
event_set(&ev, fd, EV_READ | EV_PERSIST, callback, &ev);
event_add(&ev, NULL); //加入event, 沒有設定timeout
在event_set裡面的EV_PERSIST代表執行過callback function之後, 不要把這個event移除. 如果沒有設定這個flag的話, 每次執行過callback function, 就需要event_add一次, 不然這個event就不會作用.
參考資料 :
libevent - http://monkey.org/~provos/libevent/
[+/-] |
讓vim可以有變色的效果 |
在.vimrc (vim的設定檔)裡面加入
syntax on這一行, 在用vim時有程式語法的地方就會變色.
如果這樣還是不行, 就去shell的設定檔裡面 (在csh, tcsh裡面是.cshrc, 在ksh和sh裡面是.profile),
在.profile裡面加入export TERM=xterm-color
在.cshrc裡面加入setenv TERM xterm-color
如此在用vim開啟檔案的時候, 就會出現彩色的變色了.
P.S. 記得設定完.profile或是.cshrc檔以後, 要重新login, 這樣設定檔才會被重新讀取.
參考資料 :
Tsung's Blog - http://plog.longwin.com.tw/post/1/369
http://www.chu.edu.tw/~chunpo/solaris/user/docs/shell.html
2008年6月2日 星期一
[+/-] |
Pygame : 人物跟著滑鼠旋轉 |
在遊戲裡面常常會用滑鼠來控制角色的移動, 而滑鼠目前的位置和人物的連線會被當作是人物正面朝向的方向. 這裡簡單的用python裡面的math module來計算人物和滑鼠位置的夾角.
首先介紹三角函數的arc function :
atan(x) : x 代表弧度(radians)
atan2(y, x) : 計算atan(y/x)的弧度, 回傳的值在-pi和pi之間. 因為有給(x,y)的座標, 所以能判斷座 標是在那個象限裡面, 也就能知道正確的方位.
radians(x) : 把角度(degree)轉成弧度(radian)
degrees(x) : 把弧度轉成角度
因為人物移動的時候也可以用鍵盤做細微的移動, 所以角度的儲存是以degree方式儲存.
所以要讓人物面向滑鼠目前方向的角度為 :
rotate = math.degrees(math.atan2(x, y))
參考資料 :
http://docs.python.org/lib/module-math.html