关于vtable符号,可能未定义,因为该类缺少其关键功能

时间:2018-12-24 10:23:51

标签: android c++ clang++

我想调试Android本机源代码,因此我更改了clang优化级别-Os-> -O0 错误:

  

frameworks / native / services / surfaceflinger / DisplayHardware / HWComposer_hwc1.h:171:错误:未定义对“ vtable for android :: HWComposer :: HWCLayerInterface”的引用           prebuilts / gcc / linux-x86 / aarch64 / aarch64-linux-android-4.9 / aarch64-linux-android / bin / ld.gold:vtable符号可能未定义,因为该类缺少其关键功能(请参阅go / missingkeymethod)           frameworks / native / services / surfaceflinger / DisplayHardware / HWComposer_hwc1.h:171:错误:未定义对“ vtable for android :: HWComposer :: HWCLayerInterface”的引用           prebuilts / gcc / linux-x86 / aarch64 / aarch64-linux-android-4.9 / aarch64-linux-android / bin / ld.gold:vtable符号可能未定义,因为该类缺少其关键功能(请参阅go / missingkeymethod)           frameworks / native / services / surfaceflinger / DisplayHardware / HWComposer_hwc1.h:171:错误:未定义对“ vtable for android :: HWComposer :: HWCLayerInterface”的引用           prebuilts / gcc / linux-x86 / aarch64 / aarch64-linux-android-4.9 / aarch64-linux-android / bin / ld.gold:vtable符号可能未定义,因为该类缺少其关键功能(请参阅go / missingkeymethod)           frameworks / native / services / surfaceflinger / DisplayHardware / HWComposer_hwc1.h:171:错误:未定义对“ vtable for android :: HWComposer :: HWCLayerInterface”的引用           prebuilts / gcc / linux-x86 / aarch64 / aarch64-linux-android-4.9 / aarch64-linux-android / bin / ld.gold:vtable符号可能未定义,因为该类缺少其关键功能(请参阅go / missingkeymethod)           out / target / product / rk3399_box / obj / SHARED_LIBRARIES / libsurfaceflinger_intermediates / DisplayHardware / HWComposer_hwc1.o:frameworks / native / services / surfaceflinger / DisplayHardware / HWComposer_hwc1.cpp:vtable for android :: Iterable:error:reference to HWComposer :: HWCLayerInterface :: setDataspace(android_dataspace)'           out / target / product / rk3399_box / obj / SHARED_LIBRARIES / libsurfaceflinger_intermediates / DisplayHardware / HWComposer_hwc1.o:frameworks / native / services / surfaceflinger / DisplayHardware / HWComposer_hwc1.cpp:vtable对于android :: HWComposer的错误: android :: HWComposer :: HWCLayerInterface :: setDataspace(android_dataspace)'           clang ++:错误:链接器命令失败,退出代码为1(使用-v查看调用)

我不想修改android源代码,但是我想结束优化。

HWCLayerInterface:

    class HWCLayerInterface {
    protected:
        virtual ~HWCLayerInterface() { }
    public:
        virtual int32_t getCompositionType() const = 0;
        virtual uint32_t getHints() const = 0;
        virtual sp<Fence> getAndResetReleaseFence() = 0;
        virtual void setDefaultState() = 0;
        virtual void setSkip(bool skip) = 0;
        virtual void setIsCursorLayerHint(bool isCursor = true) = 0;
        virtual void setBlending(uint32_t blending) = 0;
        virtual void setTransform(uint32_t transform) = 0;
        virtual void setFrame(const Rect& frame) = 0;
        virtual void setCrop(const FloatRect& crop) = 0;
        virtual void setVisibleRegionScreen(const Region& reg) = 0;
        virtual void setSurfaceDamage(const Region& reg) = 0;
        virtual void setSidebandStream(const sp<NativeHandle>& stream) = 0;
        virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
        virtual void setAcquireFenceFd(int fenceFd) = 0;
        virtual void setPlaneAlpha(uint8_t alpha) = 0;
        virtual void onDisplayed() = 0;
        virtual void setDataspace(android_dataspace_t dataspace);
    };

HWCLayer:

    class HWCLayer : public HWCLayerInterface {
        friend class LayerListIterator;
        // select the layer at the given index
        virtual status_t setLayer(size_t index) = 0;
        virtual HWCLayer* dup() = 0;
        static HWCLayer* copy(HWCLayer *rhs) {
            return rhs ? rhs->dup() : NULL;
        }
    protected:
        virtual ~HWCLayer() { }
    };

可迭代:

    template<typename CONCRETE, typename HWCTYPE>
    class Iterable : public HWComposer::HWCLayer {
    protected:
        HWCTYPE* const mLayerList;
        HWCTYPE* mCurrentLayer;
        Iterable(HWCTYPE* layer) : mLayerList(layer), mCurrentLayer(layer),
                mIndex(0) { }
        inline HWCTYPE const * getLayer() const { return mCurrentLayer; }
        inline HWCTYPE* getLayer() { return mCurrentLayer; }
        virtual ~Iterable() { }
        size_t mIndex;
    private:
        // returns a copy of ourselves
        virtual HWComposer::HWCLayer* dup() {
            return new CONCRETE( static_cast<const CONCRETE&>(*this) );
        }
        virtual status_t setLayer(size_t index) {
            mIndex = index;
            mCurrentLayer = &mLayerList[index];
            return NO_ERROR;
        }
    };

HWCLayerVersion1:

    class HWCLayerVersion1 : public Iterable<HWCLayerVersion1, hwc_layer_1_t> {
        struct hwc_composer_device_1* mHwc;
    public:
    ......
        virtual void setDataspace(android_dataspace_t dataspace) {
            getLayer()->reserved[0] = dataspace & 0xFF;
            getLayer()->reserved[1] = (dataspace >> 8) & 0xFF;
            getLayer()->reserved[2] = (dataspace >> 16) & 0xFF;
            getLayer()->reserved[3] = (dataspace >> 24) & 0xFF;
        }
    }

当我将优化级别更改为-O2或:

class HWCLayerInterface {
    protected:
        virtual ~HWCLayerInterface() { }
    public:
        virtual int32_t getCompositionType() const = 0;
        virtual uint32_t getHints() const = 0;
        virtual sp<Fence> getAndResetReleaseFence() = 0;
        virtual void setDefaultState() = 0;
        virtual void setSkip(bool skip) = 0;
        virtual void setIsCursorLayerHint(bool isCursor = true) = 0;
        virtual void setBlending(uint32_t blending) = 0;
        virtual void setTransform(uint32_t transform) = 0;
        virtual void setFrame(const Rect& frame) = 0;
        virtual void setCrop(const FloatRect& crop) = 0;
        virtual void setVisibleRegionScreen(const Region& reg) = 0;
        virtual void setSurfaceDamage(const Region& reg) = 0;
        virtual void setSidebandStream(const sp<NativeHandle>& stream) = 0;
        virtual void setBuffer(const sp<GraphicBuffer>& buffer) = 0;
        virtual void setAcquireFenceFd(int fenceFd) = 0;
        virtual void setPlaneAlpha(uint8_t alpha) = 0;
        virtual void onDisplayed() = 0;
        //change to default implemented
        virtual void setDataspace(android_dataspace_t dataspace) = 0;
    };

此错误不存在。

1 个答案:

答案 0 :(得分:0)

= 0并不意味着默认实现,它意味着未实现—您保留了在指向setDataspace的指针和引用上调用HWCLayerInterface的能力,但是没有实现{ {1}}。

如果省略HWCLayerInterface::setDataspace,那么您将保证某个地方有= 0的实现,链接器将期望它存在。您收到的错误是链接程序告诉您,您已向它答应了该方法的实现,但未提供该方法。

优化级别无关紧要,如果您声明一个方法但也未定义它,则C ++代码不正确。

所以:

  • 如果要定义子级必须覆盖的虚函数,请将其声明为HWCLayerInterface::setDataspace;
  • 如果您想定义子级可以覆盖的虚函数,但是希望该函数在不被覆盖的情况下不执行任何操作,请将其声明为空-例如= 0

为了获得良好的维护,您应该将覆盖的所有内容标记为virtual void setDataspace(android_dataspace_t dataspace) {}。然后,编译器将检查您是否确实重写了某些内容。这样既可以保护您避免难以发现的错别字,也可以避免您无法跟踪的父类中的更改,这两种情况都可以使您尝试覆盖的功能只是一些独立的功能。还要研究override以及何时适用于类和/或覆盖的函数。