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

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

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

    so true

    心懷未來,開創未來!
    隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
    數據加載中……

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

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

    而且新加的函數都是W類型,下面通過另一個例子來驗證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 閱讀(274) 評論(0)  編輯  收藏 所屬分類: C&C++

    主站蜘蛛池模板: 亚洲天堂在线视频| 日韩一级在线播放免费观看| 亚洲国产综合无码一区二区二三区| 国产午夜亚洲精品| 国产福利在线观看免费第一福利| 亚洲无删减国产精品一区| 免费毛片a线观看| 亚洲成AV人片在线观看ww| 国产日韩AV免费无码一区二区| 国产自偷亚洲精品页65页| 91视频免费观看| 亚洲AV美女一区二区三区| 久久精品人成免费| 亚洲伊人久久大香线蕉在观| 国产v精品成人免费视频400条| 一本色道久久88亚洲精品综合| 在线播放高清国语自产拍免费 | 久久青草亚洲AV无码麻豆| 在线人成免费视频69国产| 亚洲高清在线观看| 国内精自视频品线六区免费| 久久亚洲最大成人网4438| 情侣视频精品免费的国产| 四虎影视在线看免费观看| 亚洲乱码精品久久久久..| 免费不卡在线观看AV| 99久久婷婷国产综合亚洲| 国产成人免费永久播放视频平台| 一本一道dvd在线观看免费视频| 国产亚洲成av片在线观看| 亚洲免费闲人蜜桃| 日韩国产欧美亚洲v片| 亚洲日韩aⅴ在线视频| 国产成人午夜精品免费视频| 老妇激情毛片免费| 亚洲成a人片77777老司机| 成年女人喷潮毛片免费播放| 一二三区免费视频| 亚洲精品视频观看| 亚洲AV无码乱码精品国产| 一区二区三区在线免费看|