首页 > 解决方案 > 关于 vtable 符号可能未定义,因为该类缺少其关键功能

问题描述

我想调试android原生源代码,所以我改变了clang优化级别-Os->-O0 错误:

frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h:171:error: undefined reference to '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)出/目标/产品/rk3399_box/obj/SHARED_LIBRARIES/libsurfaceflinger_intermediates/DisplayHardware/HWComposer_hwc1.o:frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp:vtable for android::Iterable: error: undefined reference to 'android::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 for android::HWComposer::HWCLayer: error: undefined reference to 'android::HWComposer::HWCLayerInterface:: setDataspace(android_dataspace)' clang++:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)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::HWComposer::HWCLayer: error: undefined reference to ' android::HWComposer::HWCLayerInterface::setDataspace(android_dataspace)' clang++: error: linker command failed with exit code 1 (使用 -v 查看调用)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::HWComposer::HWCLayer: error: undefined reference to ' android::HWComposer::HWCLayerInterface::setDataspace(android_dataspace)' clang++: error: linker command failed with exit code 1 (使用 -v 查看调用)链接器命令失败,退出代码为 1(使用 -v 查看调用)链接器命令失败,退出代码为 1(使用 -v 查看调用)

我不想修改android源代码,但我想关闭优化。

HWCLayer接口:

    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);
    };

硬件层:

    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;
        }
    }

当我将优化级别更改为-O2or 时:

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;
    };

此错误不存在。

标签: androidc++clang++

解决方案


= 0并不意味着默认实现,它意味着未实现 - 您保留调用setDataspace指针和引用的能力 aHWCLayerInterface但没有实现HWCLayerInterface::setDataspace.

如果你省略了,= 0那么你保证在HWCLayerInterface::setDataspace某个地方有一个实现,并且链接器会期望它存在。您得到的错误是链接器告诉您您向它承诺了该方法的实现,但没有提供。

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

所以:

  • 如果你想定义一个孩子必须重写的虚函数,把它声明为= 0;
  • 如果你想定义一个子函数可以覆盖的虚函数,但如果没有被覆盖,但希望该函数什么都不做,请将其声明为空 - 例如virtual void setDataspace(android_dataspace_t dataspace) {}.

为了进行良好的维护,您应该将覆盖的任何内容标记为override. 然后编译器会检查你是否真的覆盖了某些东西。这将保护您免受难以发现的拼写错误和您未能跟踪的父类中的更改,其中任何一个都可以使您尝试的覆盖变成一些独立的功能。还要研究final何时适合应用于类和/或覆盖的函数。


推荐阅读