<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    so true

    心懷未來,開創(chuàng)未來!
    隨筆 - 160, 文章 - 0, 評(píng)論 - 40, 引用 - 0
    數(shù)據(jù)加載中……

    some notes on linking with shared library

    ==> Object.h <==
    #include <stdio.h>

    class Object {
    public:
        Object();
    #ifdef TEST
        void NoneVirtualFunc() {
            printf("%s, size of class:%lu\n", __PRETTY_FUNCTION__, sizeof(Object));
        }
    #endif

    #ifdef TEST
        virtual void Func2();
        virtual void Func1();
    #else
        virtual void Func1();
        virtual void Func2();
    #endif
        virtual void Access();

    #ifdef TEST
        void SetOther(int other) {
            m_other = other;
        }
        virtual void Other() {
            printf("%s\n", __PRETTY_FUNCTION__);
        }
    #endif

    private:
        int m_i1;
    #ifdef TEST
        int m_other;
    #endif
        int m_i2;
    };

    ==> Object.cpp <==
    #include "Object.h"

    Object::Object(): m_i1(1), m_i2(2) {
        printf("%s, constructor init, i1:%d, i2:%d\n", __PRETTY_FUNCTION__, m_i1, m_i2);
    }

    void Object::Func1() {
        printf("%s\n", __PRETTY_FUNCTION__);
    }

    void Object::Func2() {
        printf("%s\n", __PRETTY_FUNCTION__);
    }

    void Object::Access() {
        printf("%s, size of class:%lu, i1:%d, i2:%d\n", __PRETTY_FUNCTION__, sizeof(Object), m_i1, m_i2);
    }

    ==> test.cpp <==
    #include "Object.h"

    //for more details about vtable, see: http://blog.csdn.net/haoel/article/details/1948051

    int main(int argc, char* argv[]) {
        Object* obj = new Object();

        obj->Func1();
        obj->Func2();
    #ifdef TEST
        obj->SetOther(1000);
    #endif
        obj->Access();

    #ifdef TEST
        obj->NoneVirtualFunc();
        obj->Other(); //segmentation fault
    #endif

        return 0;
    }


    ==> Makefile <==
    all:
        @g++ -g -fPIC -o Object.o -fno-rtti -c Object.cpp
        @g++ -shared -o libObject.so Object.o
        @g++ -g -Wall test.cpp -o test -L. -lObject -Wl,-rpath=.
        @./test
        @rm -f test *.o *.so core*


    test:
        @g++ -g -fPIC -o Object.o -fno-rtti -c Object.cpp
        @g++ -shared -o libObject.so Object.o
        @g++ -g -Wall test.cpp -o test -L. -lObject -Wl,-rpath=. -DTEST
        @./test
        @rm -f test *.o *.so core*

    ==> RESULT <==
    $ make
    Object::Object(), constructor init, i1:1, i2:2
    virtual void Object::Func1()
    virtual void Object::Func2()
    virtual void Object::Access(), size of class:16, i1:1, i2:2

    $ make test
    Object::Object(), constructor init, i1:1, i2:2
    virtual void Object::Func2()
    virtual void Object::Func1()
    virtual void Object::Access(), size of class:16, i1:1, i2:1000
    void Object::NoneVirtualFunc(), size of class:24
    make: *** [test] Segmentation fault (core dumped)
    make: *** Deleting file `test'

    ==> KNOWLEDGE <==
    一個(gè)類一旦已經(jīng)編譯成so了,那么虛函數(shù)以及成員變量就都確定了,也就是影響一個(gè)類的內(nèi)存映像的東西都是確定的了。
    所以,修改頭文件時(shí)需要遵循以下原則:
    1。可以隨意添加非虛函數(shù);
    2。不要修改虛函數(shù)的相對(duì)位置,更不要添加新的虛函數(shù);
    3。最好不要添加新的成員變量,如果添加也要在所有成員變量的后面添加,不過如果你不清楚so里的用法的話,很有可能出問題;

    其實(shí),說到本質(zhì)上,就是要心里很清楚,修改前和修改后,該類的內(nèi)存映像到底是怎樣的,固化在so里的代碼是不會(huì)再變化了;
    有興趣的,可以debug看下虛函數(shù)表里指針的情況;如果不用-fno-rtti參數(shù),那么vtable里會(huì)多出兩項(xiàng)用于typeinfo相關(guān)的內(nèi)容;
    增加了新的虛函數(shù)后,通過nm -C test | grep Object可以看到,生成的可執(zhí)行程序里是不會(huì)有Other這個(gè)虛函數(shù)的:
    00000000004008f8 W Object::NoneVirtualFunc()
    0000000000400920 W Object::SetOther(int)
                     U Object::Object()
    0000000000400a60 r Object::NoneVirtualFunc()::__PRETTY_FUNCTION__

    而且新加的函數(shù)都是W類型,下面通過另一個(gè)例子來驗(yàn)證W類型:
    ==> Object.h <==
    #include <stdio.h>

    class Object {
    public:
        void func() {
            printf("It's the implementation of %s in header file\n", __PRETTY_FUNCTION__);
        }
    };

    ==> test.cpp <==
    #include <stdio.h>
    #include "Object.h"

    int main(int argc, char* argv[]) {
        Object obj;
        obj.func();
        return 0;
    }

    ==> RESULT <==
    $ g++ -o test test.cpp
    $ ./test
    It's the implementation of void Object::func() in header file

    ==> Object.cpp <==
    #include <stdio.h>
    class Object {
    public:
        void func();
    };

    void Object::func() {
        printf("%s\n", __PRETTY_FUNCTION__);
    }

    ==> RESULT <==
    $ g++ -c -o Object.o Object.cpp
    $ g++ -o test test.cpp Object.o
    $ ./test
    void Object::func()

    posted on 2015-03-12 20:50 so true 閱讀(283) 評(píng)論(0)  編輯  收藏 所屬分類: C&C++

    主站蜘蛛池模板: 亚洲熟妇无码AV不卡在线播放 | 国产三级免费电影| 特级aaaaaaaaa毛片免费视频| 亚洲国产高清在线一区二区三区| 国产成年无码久久久免费| 亚洲无砖砖区免费| 午夜国产大片免费观看| 日本免费高清视频| 美女羞羞免费视频网站| 久久精品国产亚洲综合色| 亚州免费一级毛片| 国产亚洲综合久久| 亚洲精品韩国美女在线| 亚洲AV日韩精品一区二区三区| 亚洲三级高清免费| 国产L精品国产亚洲区久久| 999久久久免费精品国产| 亚洲国产情侣一区二区三区| 亚洲AV日韩精品一区二区三区| 日韩免费无码一区二区三区 | 一级毛片免费播放| 国产亚洲精品免费| 亚洲电影唐人社一区二区| 亚洲一级特黄大片在线观看| 野花高清在线观看免费3中文| 中文字幕在线视频免费观看| 亚洲国产精品一区二区成人片国内 | 日本免费人成黄页在线观看视频| 国产在线观看免费av站| 亚洲欧美国产欧美色欲| 在线播放高清国语自产拍免费| a毛片免费全部在线播放**| 久久精品国产亚洲av品善| 亚洲成人一级电影| 亚洲另类激情综合偷自拍图 | 亚洲人成电影在线观看青青| 亚洲中文字幕无码不卡电影| 国产乱色精品成人免费视频| 青春禁区视频在线观看直播免费| 久久久久免费看黄a级试看| 又大又硬又粗又黄的视频免费看|