声网Agora:本地服务端录制编译librecording.so文件不成功

本文介绍了如何在Linux系统上安装glibc-static和libstdc++-static库,以支持C++静态链接,以及如何修改AgoraRecordingSDK的编译脚本,确保跨平台兼容性。重点在于处理JNI接口和清理旧的头文件。

尝试以下几个方法

一、安装 GNU C 库 和 GNU 编译器集合的 C++ 标准库

yum install glibc-static libstdc++-static -y

glibc-static 提供了 C 标准库函数的静态库。这些在构建静态链接可执行文件时是必需的,静态链接的程序会在自身内部包含所有必要的库代码,而不是在运行时依赖共享库。

libstdc++-static 提供了 C++ 标准库的静态库。类似于 glibc-static,它在创建静态链接的 C++ 应用程序时会被用到。

二、修改编译脚本

Agora_Recording_SDK_for_Linux_FULL/samples/java/build.sh
将原有build_java()方法替换为

build_java()

{

  createBinFloder

   

  jniLayer="./native/jni"

  javaClassPath="./bin"

  javac src/io/agora/recording/common/*.java src/io/agora/recording/*.java src/io/agora/recording/test/*.java -d bin -Xlint:unchecked

  #clean previous jni file

  rm -f $jniLayer/io_agora_recording_RecordingSDK.h

  javah -d ./native/jni -classpath ./bin io.agora.recording.RecordingSDK

}


注意:不同平台需要重新编译

SystemMonoBase.onError: Method body is null. shcx.libedn.EdnUtil::init UnityEngine.Debug:LogError(Object) shcx.system.SystemMonoBase:onError(Exception) shcx.system.SystemProxy:onError(Exception) shcx.system.<prepare>d__20:MoveNext() shcx.system.SystemBase:prepare() shcx.system.<prepare>d__15:MoveNext() shcx.system.SystemMonoBase:prepare() shcx.system.<prepareSystems>d__30:MoveNext() shcx.system.<prepare>d__15:MoveNext() shcx.system.<prepare>d__20:MoveNext() shcx.system.<prepareSystems>d__3:MoveNext() shcx.config.<prepareSystems>d__6:MoveNext() shcx.asset.<prepareSystems>d__1:MoveNext() shcx.asset.<preloadAssets>d__23:MoveNext() shcx.asset.<loadAssetsAsync>d__14:MoveNext() shcx.asset.<loadArrayAsync>d__6`1:MoveNext() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTaskMethodBuilder:Start(TStateMachine&) Cysharp.Threading.Tasks.CompilerServices.AsyncUniTaskMethodBuilder:Start(TStateMachine&) Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:Run() Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.AwaiterActions:Continuation(Object) Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.UniTaskCompletionSourceCore`1:TrySetResult(TResult) Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:SetResult() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTaskMethodBuilder:SetResult() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:Run() Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.AwaiterActions:Continuation(Object) Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.UniTaskCompletionSourceCore`1:TrySetResult(TResult) Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:SetResult() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTaskMethodBuilder:SetResult() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:Run() Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.AwaiterActions:Continuation(Object) Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.UniTaskCompletionSourceCore`1:TrySetResult(TResult) Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:SetResult() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTaskMethodBuilder:SetResult() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:Run() Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.AwaiterActions:Continuation(Object) Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.UniTaskCompletionSourceCore`1:TrySetResult(TResult) Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:SetResult() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTaskMethodBuilder:SetResult() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:Run() Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.AwaiterActions:Continuation(Object) Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.UniTaskCompletionSourceCore`1:TrySetResult(TResult) Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:SetResult() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTaskMethodBuilder:SetResult() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:Run() Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.AwaiterActions:Continuation(Object) Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.UniTaskCompletionSourceCore`1:TrySetResult(TResult) Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:SetResult() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTaskMethodBuilder:SetResult() Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1:Run() Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.AwaiterActions:Continuation(Object) Agora.Rtc.AudioDeviceManagerImpl:Dispose() Cysharp.Threading.Tasks.UniTaskCompletionSourceCore`1:TrySetResult(TResult) 讲解
最新发布
05-27
### 方法体为空的异常分析 当遇到 `Method body is null` 的错误提示时,通常表示某个方法未被正确实现或者其定义存在问题。以下是可能的原因以及对应的解决方案: #### 可能原因一:编译器优化或配置问题 某些情况下,如果项目中的类文件经过了恰当的字节码修改工具(如 ProGuard 或 R8),可能会导致方法体丢失。这种现象常见于 Java 和 Unity 项目的混淆阶段。 - 如果正在使用 Unity 并集成了第三方库,则需要确认该库是否支持 AOT 编译模式[^1]。 - 对于 Java 项目,可以尝试禁用代码混淆或将受影响的方法加入到保留列表中[^2]。 ```java // 示例:ProGuard 配置文件中添加保持规则 -keep class shcx.libedn.EdnUtil { *; } ``` --- #### 可能原因二:动态代理或反射调用失败 在通过反射机制访问目标方法时,如果没有找到对应的方法签名,也可能抛出类似的错误消息。 - 确认 `EdnUtil.init()` 是否存在,并且它的修饰符允许外部访问(即非 private/protected)[^3]。 - 使用调试工具打印堆栈跟踪信息以便定位具体发生的位置。 ```csharp try { var method = typeof(shcx.libedn.EdnUtil).GetMethod("init", BindingFlags.Public | BindingFlags.Static); if (method != null && method.GetMethodBody() == null) { Debug.LogError("The method body of EdnUtil.init is missing."); } else { method.Invoke(null, null); // 调用静态方法 } } catch (Exception e) { Debug.LogException(e); } ``` --- #### 可能原因三:依赖版本冲突 同版本间的 API 兼容可能导致此类问题。例如,在升级 Unity 版本或其他插件之后,旧版接口可能再有效。 - 检查当前使用的 `shcx.libedn` 库版本号及其文档说明,确保它与应用程序环境相匹配[^4]。 - 更新至最新稳定版本,同时注意查看发行日志了解潜在破坏性变更。 --- #### 日志记录改进建议 为了更方便排查此类型的 bug ,可以在关键路径处增加详细的日志输出语句。比如下面这段伪代码展示了如何捕获更多上下文数据: ```csharp public static void SafeInit() { try { shcx.libedn.EdnUtil.init(); } catch (System.Exception ex) { string errorMessage = $"Failed to initialize EdnUtil due to exception: {ex.Message}"; UnityEngine.Debug.LogError(errorMessage); // 将完整的 stack trace 输出到控制台 System.Diagnostics.StackTrace st = new System.Diagnostics.StackTrace(ex, true); foreach (var frame in st.GetFrames()) { UnityEngine.Debug.LogWarning($"Stack Frame Info: {frame}"); } throw; } } ``` --- #### 总结 综上所述,“Method body is null”的根本原因是多方面的,需逐一排除上述提到的各种可能性才能彻底解决问题。务必仔细阅读官方文档和技术论坛上的相关内容来辅助诊断过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值