0、问题背景
自己的程序调用libjack64.dll启动时就发生异常崩溃,自己的开发环境是64位win10,在64位win7下测试可以正常运行。针对这个问题尝试了一些解决方案后,最终确定是使用的libjack64.dll和自己的应用程序库不兼容所导致的。
1、尝试使用weak_libjack
使用weak_libjack的步骤如下:
0)把weak_libjack所有源文件拷到工程中
1)将所有#include<jack/*>替换为#include<weak_libjack.h>
2)把weak_libjack.c添加到工程中进行编译
3)定义USE_WEAK_JACK宏来使用weak-linking,通常形式为CFLAGS+=-DUSE_WEAK_JACK CXXFLAGS+=-DUSE_WEAK_JACK
4)定义USE_WEAK_JACK后不能直接链接libjack(-ljack)
将weak_libjack添加到jackrack模块中的运行结果依然会崩溃,但windows控制台demo引入weak_libjack可以解决加载libjack64崩溃的问题。另外将控制台工程将随机基地址设置为NO后,该程序也能够正常运行,32位windows控制台程序和mlt_test一样能够正常运行,无需任何设置。
2、MinGW编译libjack64.dll和libjackserver64.dll
jack的GitHub库中的readme有各个平台下的编译步骤,但本人按照原有步骤使用MinGW编译windows版并没有成功。用MinGW编译也有两种方式,一种是直接在msys命令行中编译,另一种是使用CodeBlocks进行编译,这两种编译方式都需要自己做一些编译前的配置和准备。
(1)命令行形式编译
官方文档中的编译步骤在本人环境下并没有编译成功,
1)./waf configure --platform=win32
运行configure会失败,原因是在源码common目录下的wscript脚本中包含检测regex库的过程,而jack源码中是不包含该模块的,需要自己下载或编译regex,这里编译一个64位的libregex.dll,并将该dll放到任意位置,在wscript中build函数中加入bld.read_shlib(‘regex’,paths = [‘E:\workspace\jack2’]),其中的绝对路径是libregex.dll的位置,该句是为了在编译时能正常链接libregex.dll。另外build函数中的uselib.append(‘regex’),原始代码的”regex”是大写的,实际上编译是无法通过的,需要区分大小写。
2)./waf build -v
完成编译后,在源码的build\common下可以找到生成的libjack-0.dll和libjackserver-0.dll。
(2)CodeBlocks编译
1)使用CodeBlocks打开jack2\windows目录下jackd.workspace,各个工程项目导入如下:
2)然后根据自己的实际环境设置编译选项,个人设置如下所示。
3)接着依次选中libjack和libjackserver依次编译,直接编译会失败,这是因为这两个项目都关联了tre-0.8.0(一个正则表达式库),但jack源码中并没有这个库,所以还需要另外下载该库。在jack2\windows目录下创建一个tre-0.8.0目录,然后将tre项目中的lib和win32两个目录拷到tre-0.8.0中,最后将win32\config.h中的#define snprintf sprintf_s注释掉,否则会出现重定义的错误提示。
4)编译成功后,在windows\Release64\bin下可以找到libjack64.dll和libjackserver64.dll
(3)测试的结果表明以上两种方式编译的dll都能够正常使用,但这里推荐使用CodeBlocks进行编译,除了更方便外,编译的结果和用MSVC编译的dll名称一样,在自己的应用中无需修改配置文件,直接替换libjack64.dll和libjackserver64.dll即可。
(4)如果安装过官网的windows版jack,在系统盘下会有一个libjack64.dll,libjackrack.dll会先找到该路径下的libjack64.dll,所以运行结果仍然是崩溃,需要将该libjack64.dll先删除。
3、小结
搜索了jack库在win10下运行崩溃的问题,发现还是有类似问题的反馈,大多解决建议是让自己的程序不直接依赖libjack64.dll,在运行期间再动态调用jack中的函数,与此对应的第三方解决方案有weak_libjack等,自己一开始就想通过引入weak_libjack来解决该问题。将weak_libjack引入jackrack模块中后的测试结果仍然是运行崩溃,所以还是决定重新编译jack。通过depends查看libjack64.dll和libjackserver64.dll的依赖,可以推断出jack官网windows安装包中的libjack64.dll和libjackserver64.dll是MSVC编译的,由于自己的程序库是MinGW编译的,所以这里面会存在一个兼容性的问题,而且这个问题在32位系统中没有出现,但在64位环境下就会出现,于是就用MinGW重新编译jack来验证一下这个猜测。