• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天衣有縫

            冠蓋滿京華,斯人獨憔悴~
            posts - 35, comments - 115, trackbacks - 0, articles - 0
               :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
            內核當然可用用c++來些,但是相對c來說有許多要注意的地方,我們不得不關掉一些特性。這里只提一些gcc相關的內容,Microsoft VC我沒有嘗試。轉載請注明原創:天衣有縫(http://www.shnenglu.com/jinglexy),MSN: jinglexy at yahoo dot com dot cn

            1)g++選項-nostartfiles:用戶環境的在main之前調用的代碼,當然不能使用了
            2)全局對象:每種類型都有自己的構造函數,如果不自己編寫代碼調用,它們不會執行。
            這包括所有全局對象和局部static對象,建議的做法是在內核棧建立后,c++運行代碼執行之前
            調用構造函數,如果構造函數沒有運行(假設里面有分配內存之類的操作),后果很嚴重:)
            我們可以這樣做:
            先修改gnu-ld鏈接腳本
            .data : {
                start_ctors = .;
                *(.ctor*)
                end_ctors = .;
                start_dtors = .;
                *(.dtor*)
                end_dtors = .;

                *(.data)
            }
            這樣構造函數的指針就都保存在start_ctors 和end_ctors之間的內存中了,構造函數其實就是void foo(void);形式的函數,編寫一個for循環

            調用它即可;析構函數也是一樣的。當每個構造函數調用完后,gcc會自動調用一個函數:
            int __cxa_atexit(void (* f)(void *), void *p, void *d);
            當內核退出時,會執行一個函數:
            void __cxa_finalize(void *d);
            這兩個函數必須按上面格式定義,g++是這樣規定的。看看下面的代碼就明白了:
            extern "C"
                    {
                    int __cxa_atexit(void (*f)(void *), void *p, void *d);
                    void __cxa_finalize(void *d);
                    };

            void *__dso_handle; /*only the address of this symbol is taken by gcc*/

            struct object
            {
                    void (*f)(void*);
                    void *p;
                    void *d;
            } object[32] = {0};
            unsigned int iObject = 0;

            int __cxa_atexit(void (*f)(void *), void *p, void *d)
            {
                    if (iObject >= 32) return -1;
                    object[iObject].f = f;
                    object[iObject].p = p;
                    object[iObject].d = d;
                    ++iObject;
                    return 0;
            }

            /* This currently destroys all objects */
            void __cxa_finalize(void *d)
            {
                    unsigned int i = iObject;
                    for (; i > 0; --i)
                    {
                            --iObject;
                            object[iObject].f(object[iObject].p);
                    }
            }

            3)new和delete:在完成內存管理后,重載類的new和delete函數
            4)-nostdlib:把標準庫禁用掉,最近有了移植stl到內核的想法
            5)RTTI:最好是禁止它,這樣不能用typeid 和 dynamic_cast了
            6)禁用異常:-fno-exceptions,這個和操作系統太緊密了
            7)純虛函數,如果子類沒有實現父類中的純虛函數,鏈接到下面默認例程:
            extern "C" void __cxa_pure_virtual()
            {
                // print error message
            }
            雖然不是為了定義純虛類的對象,但是鏈接時編譯器會抱怨,所以定義上面函數使編譯通過。
            8)如果一定要使用異常,rtti,new/delete,gcc中提供了靜態庫:libgcc/libsupc++,
            還得寫這個庫的一些基礎函數,覺得它應該是在上層抽象出接口,將底層實現空出來給用戶實現。
            而且代碼本身非常復雜,網絡上也沒有任何中文資料。
            指令:
            readelf -a `gcc -print-libgcc-file-name`
            里面定義了很多的函數。

            Feedback

            # re: C++寫內核需要注意的一些事情(原創)  回復  更多評論   

            2007-12-22 09:30 by Nubix
            頂一下
            国产香蕉97碰碰久久人人| 国产V亚洲V天堂无码久久久| 久久国产精品二国产精品| 久久99精品久久久久久秒播| 亚洲日本久久久午夜精品| 亚洲精品无码久久久久| 天天爽天天爽天天片a久久网| 性高朝久久久久久久久久| 蜜臀av性久久久久蜜臀aⅴ麻豆| 亚洲天堂久久精品| 久久伊人精品一区二区三区| 91视频国产91久久久| 久久夜色精品国产亚洲av| 日本强好片久久久久久AAA| 国产精品久久久久久久久久免费| 日产精品久久久久久久| 国产免费福利体检区久久| 国产激情久久久久久熟女老人| 精品久久久久久| 波多野结衣AV无码久久一区| 国产成人久久久精品二区三区| 亚洲欧美日韩中文久久| 久久996热精品xxxx| 国产一级做a爰片久久毛片| 777午夜精品久久av蜜臀| 亚洲国产成人乱码精品女人久久久不卡 | 国内精品久久久人妻中文字幕| 国产成人精品久久| 亚洲国产成人久久精品动漫| 精品久久久中文字幕人妻| 久久久久无码中| 丰满少妇人妻久久久久久4| 99久久99这里只有免费费精品| 日韩欧美亚洲综合久久| 久久天天躁夜夜躁狠狠躁2022 | 无遮挡粉嫩小泬久久久久久久| 久久综合久久性久99毛片| 国产精品无码久久久久| 久久本道久久综合伊人| 亚洲国产精品无码久久九九 | 久久偷看各类wc女厕嘘嘘|