管理中心
我的
|

3D Engine

同步编译失败

A模块包含a.so,B模块包含b.so。a.so调用b.so的函数,b.so也调用a.so的函数。按照正常编译步骤,无论先编译哪个so,都会编译失败。
点赞
收藏
回复
4
分享
举报
浏览223 发布于2025-08-15 14:11河南
全部评论
最多点赞
最新发布
最早发布

1.楼主当前的调用模式存在循环依赖:
cke_544.png

2.楼主可以从依赖层面进行抽离,将互相调用的东西抽离出来放顶层给两个模块公共使用
cke_2520.png

4楼回复于2025-08-20 13:44 来自湖南

楼主好,当两个动态链接库(a.so和b.so)存在循环依赖时,(即a.so调用b.so的函数,b.so也调用a.so的函数),直接编译会导致符号解析失败。因为传统的隐式依赖链会在编译阶段互相要求对方已存在符号,从而形成死锁。

可以通过 dlopen + dlsym 动态加载实现编译解耦,将隐式依赖转为显式依赖解决,下面是解决步骤

1. 这里以a.cpp为例修改代码逻辑

// a.cpp

#include <dlfcn.h>

#include "a.h"

extern "C" {  // 使用extern "C"避免C++名称修饰

    int add(int a, int b) { 

        // 动态加载b.so

        void* handle = dlopen("libb.so", RTLD_LAZY);

        if (!handle) {

            return -1;

        }

        

        // 获取b.so中的函数指针

        typedef int (*sub_func_t)(int, int);

        sub_func_t sub = (sub_func_t)dlsym(handle, "sub");

        

        int res = sub(a, b);

        dlclose(handle);

        return a + b + res; 

    }

}

2. 调整CMake配置

# A模块的CMakeLists.txt

add_library(a SHARED a.cpp)

# 无需直接链接b.so
# B模块的CMakeLists.txt 

add_library(b SHARED b.cpp)

# 无需直接链接a.so

3. 运行路径管理

在ArkTS侧传递SO沙箱路径:


let projectPath = getContext().bundleCodeDir;

let soPathA = `${projectPath}/libs/${abi}/liba.so`;

let soPathB = `${projectPath}/libs/${abi}/libb.so`;

Native侧通过ArkTS传入的路径加载:

// 在b.cpp中动态加载a.so

void* handle = dlopen(arktsPath, RTLD_LAZY); // arktsPath从ArkTS传入
展开全部
3楼回复于2025-08-18 12:11 来自河北

循环依赖导致编译时链接器无法解析相互引用的符号,传统静态链接方式无法处理a.so与b.so的交叉调用关系

对模块相互依赖进行解耦

// A模块a.cpp改造
extern "C" {
    #include <dlfcn.h>
    typedef int (*FUNC_SUB)(int, int);
    
    int add(int a, int b) {
        void* handle = dlopen("libb.so", RTLD_LAZY);
        FUNC_SUB sub = (FUNC_SUB)dlsym(handle, "sub");
        int res = sub(a, b);
        dlclose(handle);
        return a + b + res;
    }
}

// B模块b.cpp改造
extern "C" {
    #include <dlfcn.h>
    typedef int (*FUNC_ADD)(int, int);
    
    int sub(int a, int b) {
        void* handle = dlopen("liba.so", RTLD_LAZY);
        FUNC_ADD add = (FUNC_ADD)dlsym(handle, "add");
        int res = add(a, b);
        dlclose(handle);
        return a - b + res;
    }
}

参考地址

https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs/faqs-ndk-71

展开全部
2楼回复于2025-08-18 11:16 来自安徽
任何语言里都要避免交叉引用
1楼回复于2025-08-15 23:54 来自浙江
写回答
新增插入模板功能
一键使用模板,快速填写内容,轻松发帖~
知道了
  • 为了保障您的信息安全,请勿上传您的敏感个人信息(如您的密码等信息)和您的敏感资产信息(如关键源代码、签名私钥、调试安装包、业务日志等信息),且您需自行承担由此产生的信息泄露等安全风险。
  • 如您发布的内容为转载内容,请注明内容来源。

我要提问题

了解社区公约,与您携手共创和谐专业的开发者社区。