《依赖循环(Dependency Cycle)》

一、错误解析:

        错误信息中的依赖关系如下:

ERROR Dependency cycle:
[OHOS INFO] [GN]   //*/*/*/*:libusb_driver ->
[OHOS INFO] [GN]   //*/*/*/*:libusb_adapter ->
[OHOS INFO] [GN]   //*/*/*/*:libusb_driver ->

        可以看到,最终依赖链又回到了最开始的模块 libusb_driver,形成了一个循环依赖。换句话说,模块 libusb_driver在某个时刻需要 libusb_adapter,而 libusb_adapter 又需要 libusb_driver,形成了一个闭环。 

二、为什么会出问题?

  • 编译顺序问题:在这种情况下,编译系统无法决定应该先编译哪个模块,因为它们互相依赖。编译系统不能解决依赖循环的问题,因此导致编译失败。

  • 设计问题:这种依赖循环通常是因为模块之间的关系设计不当。某些模块可能不应该直接或间接依赖于彼此,导致这种循环依赖。

三、应用场景:

1、libusb_driver里面需要编写一个回调类UsbSaSubscriber,用来识别设备插入USB,触发回调LoadUsbSa,拉起usb服务。

class UsbSaSubscriber : {
public:
    UsbSaSubscriber();
    ~UsbSaSubscriber();
    int32_t LoadUsbSa(const int32_t &eventId);
private:
    static UsbdLoadService loadUsbService_;
    static UsbdLoadService loadHdfEdm_;
};

 2、libusb_driver需要调用libusb_adapter 里面的接口(libusb_driver的gn里面需要添加对libusb_adapter 的依赖)。

  deps = [
    "${usb_driver_path}/libusb_adapter:libusb_adapter",
  ]

3、 libusb_adapter 里面事件发生后需要触发回调,调用LoadUsbSa回调函数。然后拉起服务。(libusb_adapter gn需要添加对libusb_driver的依赖

  deps = [
    "${usb_driver_path}/hdi_service:libusb_driver",
  ]

这样就形成了循环依赖。

四、解决方法:

  1. 拆分依赖:检查每个模块之间的依赖关系,是否存在不必要的相互依赖。可以尝试将一些功能拆分到其他模块,避免形成循环依赖。

  2. 引入中间层:你可以通过引入一个中间层或抽象层来打破循环依赖。比如创建一个新的模块,专门负责协调这几个模块的依赖关系。

  3. 调整模块关系:调整模块之间的依赖顺序,尽量避免模块之间直接依赖,或者尝试使用接口(interface)来解耦依赖。

  4. 依赖注入:在某些情况下,使用依赖注入的方式可以帮助避免循环依赖问题。通过依赖注入,你可以将模块之间的依赖显式地注入到需要它们的地方,而不是让模块之间直接依赖。

 五、具体解决方法:

1、在libusb_adapter 写一个LibUsbSaSubscriber 作为父类。libusb_driver去继承LibUsbSaSubscriber。


class LibUsbSaSubscriber : public RefBase{
public:
    LibUsbSaSubscriber() {};
    virtual ~LibUsbSaSubscriber() {};
    virtual int32_t LoadUsbSa(const int32_t &eventId) { return 0; };
};


class UsbSaSubscriber : public LibUsbSaSubscriber {
public:
    UsbSaSubscriber();
    ~UsbSaSubscriber() override = default;
    int32_t LoadUsbSa(const int32_t &eventId) override;
};

sptr<LibUsbSaSubscriber> libUsbSaSubscriber = new UsbSaSubscriber();
ret = LibusbAdapter::GetInstance()->SetLoadUsbSaSubscriber(libUsbSaSubscriber);

2、创建LibUsbSaSubscriber的对象,new UsbSaSubscriber,调用子类的回调函数。达到解循环引用的目的。

六、实例代码:

#include <iostream>
using namespace std;

class A {
public:
    virtual void LoadUsbSa() {  // 将方法声明为虚函数
        cout << "父类A的LoadUsbSa方法" << endl;
    }
};

class B : public A {
public:
    void LoadUsbSa() override {  // 子类B重写父类方法
        cout << "子类B的LoadUsbSa方法" << endl;
    }
};

int main() {
    A* obj = new B();  // 基类指针指向派生类对象
    obj->LoadUsbSa();   // 调用虚函数,执行子类B的实现

    delete obj;  // 删除对象,确保调用正确的析构函数
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值