編輯:關於Android編程
1.看源碼必須搞懂Android的數據結構。在init源代碼中雙向鏈表listnode使用很多,它只有prev和next兩個指針,沒有任何數據成員。這個和linux內核的list_head如出一轍,由此可見安卓深受linux內核的影響的。本來來分析一下這個listnode數據結構。
這裡需要考慮的一個問題是,鏈表操作都是通過listnode進行的,但是那不過是個連接件,如果我們手上有個宿主結構,那當然知道了它的某個listnode在哪裡,從而以此為參數調用list_add和list_del函數;可是,反過來,當我們順著鏈表取得其中一項的listnode結構時,又怎樣找到其宿主結構呢?在listnode結構中並沒有指向其宿主結構的指針啊。畢竟,我們我真正關心的是宿主結構,而不是連接件。對於這個問題,我們舉例內核中的list_head的例子來解決。內核的page結構體含有list_head成員,問題是:知道list_head的地址,如何獲取page宿主的地址?下面是取自mm/page_alloc.c中的一行代碼:
page = memlist_entry(curr, struct page, list);
#define memlist_entry list_entry
135 /** 136 * list_entry get the struct for this entry 137 * @ptr: the &struct list_head pointer. 138 * @type: the type of the struct this is embedded in. 139 * @member: the name of the list_struct within the struct. 140 */ 141 #define list_entry(ptr, type, member) \ 142 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
2.測試代碼
#include#include typedef struct _listnode { struct _listnode *prev; struct _listnode *next; }listnode; #define node_to_item(node,container,member) \ (container*)(((char*)(node))-offsetof(container,member)) //向list雙向鏈表尾部添加node節點,list始終指向雙向鏈表的頭部(這個頭部只含有prev/next) void list_add_tail(listnode *list,listnode *node) { list->prev->next=node; node->prev=list->prev; node->next=list; list->prev=node; } //定義一個測試的宿主結構 typedef struct _node { int data; listnode list; }node; int main() { node n1,n2,n3,*n; listnode list,*p; n1.data=1; n2.data=2; n3.data=3; list.prev=&list; list.next=&list; list_add_tail(&list,&n1.list); list_add_tail(&list,&n2.list); list_add_tail(&list,&n3.list); for(p=list.next;p!=&list;p=p->next) { n=node_to_item(p,node,list); printf("%d\n",n->data); } return 0; }
飛信現在在生活之中運用越來越廣泛,他是中國移動推出的一款可以免費點對點短信的軟件,那麼如果我們把密碼忘記了怎麼辦呢?怎樣修改呢?下面小編來給大家介紹怎樣去找
TableLayout經常用到的屬性有:android:collapseColumns:以第0行為序,隱藏指定的列:android:collapseColumns該屬性為
游戲頁面有幾個小游戲,因為時間原因只做了第一個猜成語,是用的選擇題方式,十道題以內答對六題算闖關成功。目標效果:以下是具體操作過程 1.新建GameActivi
Android Studio配置及使用OpenCV 前言:最近在做項目移植,項目較大,在Eclipse中配置的Jni及OpenCV環境沒任何問題,但是遷移到St