<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++

    主站蜘蛛池模板: 亚洲中文字幕无码爆乳AV| 黄色网页免费观看| 最新国产AV无码专区亚洲| 无码乱肉视频免费大全合集 | 无码日韩精品一区二区免费暖暖| 久久亚洲精品国产精品婷婷| 亚洲精品无码专区在线在线播放 | 亚洲美女视频网站| 亚洲无码视频在线| 日本高清免费不卡在线| 四虎最新永久免费视频| 玖玖在线免费视频| 国产精品视频全国免费观看| 日日摸日日碰夜夜爽亚洲| 国产成人亚洲合集青青草原精品 | 黄色网址免费在线观看| 最好2018中文免费视频| 亚洲国产欧美一区二区三区| xxx毛茸茸的亚洲| 久久久婷婷五月亚洲97号色| 亚洲AV无码精品色午夜在线观看| 亚洲午夜国产精品无码老牛影视| 亚洲乱码中文字幕手机在线| 国产不卡免费视频| 国产一级淫片a免费播放口之| 成熟女人特级毛片www免费| 猫咪社区免费资源在线观看| 2019中文字幕在线电影免费| 久久久久久久岛国免费播放| 青柠影视在线观看免费| 在线涩涩免费观看国产精品| A级毛片成人网站免费看| 精品国产福利尤物免费| 一级特黄录像免费播放肥| 精品国产福利尤物免费| a级毛片高清免费视频就| 91视频免费观看| 免费人成网站在线观看不卡| 免费无码一区二区三区蜜桃| 在线毛片片免费观看| 日韩免费无码视频一区二区三区 |