一、错误解析:
错误信息中的依赖关系如下:
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",
]
这样就形成了循环依赖。
四、解决方法:
-
拆分依赖:检查每个模块之间的依赖关系,是否存在不必要的相互依赖。可以尝试将一些功能拆分到其他模块,避免形成循环依赖。
-
引入中间层:你可以通过引入一个中间层或抽象层来打破循环依赖。比如创建一个新的模块,专门负责协调这几个模块的依赖关系。
-
调整模块关系:调整模块之间的依赖顺序,尽量避免模块之间直接依赖,或者尝试使用接口(interface)来解耦依赖。
-
依赖注入:在某些情况下,使用依赖注入的方式可以帮助避免循环依赖问题。通过依赖注入,你可以将模块之间的依赖显式地注入到需要它们的地方,而不是让模块之间直接依赖。
五、具体解决方法:
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;
}