背景
webrtc的aecm消音模块在android中实践有效果,能够有效消除回音和噪音,由于windows端有个客户端程序也需要使用到消除回音的功能,所以根据源码,移植成dll通过jni给java程序调用。
过程
通过VS2017创建DLL项目
把源码拷贝到创建的项目中并导入
拷贝webrtc-based-android-aecm-master\eclipse-project\jni\aecm中的.h/.c文件到创建的项目(比如创建的项目名为DLL7)Dll7\Dll7中。
然后分别导入头文件.h和源文件.c,导入的文件的路径为刚才拷打到Dll7\Dll7中的所以.h/.c文件:
webrtc-based-android-aecm-master\eclipse-project\jni\aecm路径中的Android.mk不用拷贝,因为我们是要编译dll而不是安卓的so库。
不要直接复制.h/.c文件然后到头文件/源文件右键黏贴,这样项目会识别不到文件的;也不要直接跳过拷贝的过程,就直接导入其他路径的.h/.c文件,因为项目识别到的文件路径就不在本项目中了,复制打包源码时就会东一块西一块代码。
添加jni需要的源码
由于用到jni,所以我们需要把jni的环境加到项目中,不然比如aecm_wrapper.c中的#include <jni.h>就会报红。
右键项目的属性:
点击常规中的附加包含目录:
依据附加jdk的三个目录:
C:\Program Files\Java\jdk1.8.0_131\include
C:\Program Files\Java\jdk1.8.0_131\include\win32
C:\Program Files\Java\jdk1.8.0_131\include\win32\bridge
修改一下源码
此源码再android通过ndk编译可以,但是移植到windows端需要补充一下代码:
aecm_wrapper.c文件添加#include "echo_control_mobile.h"代码;
cpu_features_wrapper.h文件的#include <typedefs.h>改为#include "typedefs.h";
取消预编译头
取消预编译头,不然编译的时候会报错:
编译
看到如图就代表成功了:
在项目的debug目录下可以看到dll文件:
问题
如果在用jni调用库的时候提示:C:\Windows\System32\aecm.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform,这是由于运行平台是64环境,我们编译的库是32的,所以不行,进行配置就可以了,注意,这样配置后,要重新添加jni需要的源码和取消预编译头步骤:
资源
aecm源码地址
https://github.com/lhc180/webrtc-based-android-aecm
编译好的dll文件地址
https://www.aliyundrive.com/s/CvuWouLapVD
问题
打包后的dll在jdk1.8_131下调用一切正常,但是在jdk11,15,16下都会奔溃;起初还以为编译的时候“添加jni需要的源码”的步骤错了,所以尝试了java的运行环境选择15,添加jni需要的源码也选择jdk15中的include,但是也不行;后怀疑的openjdk的问题,换了Oracle的也不行;最后排除到了echo_control_mobile.c文件的第175行的aecm->sampFreq = sampFreq;行导致的奔溃,具体情况不得而知。
参考
JNI之——Can't load IA 32-bit .dll on a AMD 64-bit platform错误的解决
https://blog.csdn.net/l1028386804/article/details/46605003
windows下vscode+vs2019开发JNI的示例
https://www.yht7.com/news/147088