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

    主站蜘蛛池模板: 国产一区二区免费视频| caoporn国产精品免费| 国产精品色拉拉免费看| 亚洲视频中文字幕在线| 2020因为爱你带字幕免费观看全集 | 久久亚洲精品中文字幕| 99精品视频在线免费观看| 亚洲国产精品久久久久网站| 久久精品一本到99热免费| 亚洲人成电影在线观看青青| 无码专区永久免费AV网站| 亚洲av日韩综合一区久热| 又大又黄又粗又爽的免费视频| 高清免费久久午夜精品| 亚洲日韩乱码中文无码蜜桃臀网站| 久久久久久久99精品免费观看 | 久久久久亚洲精品天堂久久久久久| 久久久久久久久久免免费精品| 国产亚洲婷婷香蕉久久精品| 日本免费污片中国特一级| 亚洲国产av一区二区三区丶| 青草草在线视频永久免费| 无遮挡免费一区二区三区| 国产亚洲综合久久系列| 成人免费视频网站www| 久久精品亚洲日本波多野结衣| 国产精品亚洲mnbav网站 | 国产午夜免费福利红片| 国产一区二区三区免费观在线| 久久精品国产亚洲77777| 成人au免费视频影院| 国产免费牲交视频免费播放| 亚洲成AV人片久久| www.亚洲一区| 亚洲黄色免费网址| 日韩精品无码免费视频| 亚洲日韩乱码中文无码蜜桃 | 亚洲国产香蕉碰碰人人| 免费毛片在线视频| 麻豆精品不卡国产免费看| 亚洲最大天堂无码精品区|