libmfx undefined reference to `__imp_swscanf_s‘

本文介绍了如何在Windows+MSYS2环境中使用ffmpeg配置选项编译,以保留avcodec.dll并解决第三方库(如libmfx)导致的undefinedreference错误,包括使用静态链接和自定义legacy_stdio_definitions.lib的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

windows + msys2 编译 ffmpeg,想要保留对应的 avcodec.dll 的话,需要加上 "--enable-shared" 参数,这样生成的 dll 可以在自行开发程序时引入

如果有 enable 三方库的话(比如 x265,比如 libmfx -> for intel QSV HW codec),编译出来的这个 avcodec.dll ,会依赖于三方的 dll (libx265.dll,libmfx-1.dll)才能运行

如果把第三方库的内容,一起打包进 ffmpeg 对应的 dll (比如 avcodec.dll)中,这样子生成的 avcodec.dll 就不会再依赖于三方 dll 了

想要达到这个目标,需要在 config 时,加上static link 的参数:--extra-ldflags=-static --pkg-config-flags=--static

完整的命令如下:

./configure --enable-shared --enable-libx265 --enable-gpl --enable-libmfx --enable-ffnvcodec --enable-nvdec --enable-nvenc --extra-cflags=-I/d/msys64/mingw64/include/mfx --extra-ldflags=-L/d/msys64/mingw64/lib --extra-ldflags=-static --pkg-config-flags=--static


可惜的是,如果有 enable libmfx 的话,上面的 config 指令会报错,提示找不到 libmfx

查看对应的 config log (E:\ffmpeg\ffmpeg-master\ffbuild\config.log),会发现下面的异常:

gcc -L/d/msys64/mingw64/lib -static -Wl,--nxcompat,--dynamicbase -Wl,--high-entropy-va -Wl,--as-needed -Wl,--image-base,0x140000000 -o /tmp/ffconf.7AG0j4aL/test.exe /tmp/ffconf.7AG0j4aL/test.o -lmfx -lstdc++ -lole32 -luuid


D:/MinGW/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: D:/msys64/mingw64/lib\libmfx.a(libmfx_la-mfx_plugin_hive.o):(.text+0x3c): undefined reference to `__imp_swscanf_s'

(使用 visual studio 来编译libmfx 源代码生成的 libmfx.dll 也有这个问题...)

网上搜索,找到在 visual studio 下的解决方案:编译时,添加链接 "legacy_stdio_definitions.lib" 这个lib

翻了下这个 lib 对应的 cpp 文件(D:\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\crt\src\linkopts\legacy_stdio_definitions.cpp),里面重新定义了 __imp_swscanf_s 这个函数:

#ifdef _M_IX86
    #define _VCRT_DEFINE_IAT_SYMBOL_MAKE_NAME(f) _CRT_CONCATENATE(_imp__, f)
#else
    #define _VCRT_DEFINE_IAT_SYMBOL_MAKE_NAME(f) _CRT_CONCATENATE(__imp_, f)
#endif

#define _VCRT_DEFINE_IAT_SYMBOL(f)                                                          \
    extern "C" __declspec(selectany) void const* const _VCRT_DEFINE_IAT_SYMBOL_MAKE_NAME(f) \
        = reinterpret_cast<void const*>(f)

_VCRT_DEFINE_IAT_SYMBOL(swscanf_s);

其实就是用 reinterpret_cast 指向 swscanf_s 这个函数了。swscanf_s 这个是 C 的标准库函数,定义在头文件 <wchar.h>

但是,msys2 中使用 Mingw gcc/g++ 编译的话,并没有现成的 "legacy_stdio_definitions.lib" 可以直接用,它是 visual studio 自带的


Mingw gcc/g++ 中,可以参考 visual studio 的做法,自己用 g++ 重新生成一个 lib 文件,包含 __imp_swscanf_s  的定义就好了。做法如下:

  1. 新建 cpp 文件:legacy_stdio_definitions.cpp,文件内容如下。因为这里只有这一个函数出问题,就只定义了这一个,如果有遇到其他函数出问题的,可以再加上去
    1. #include <wchar.h>
      
      extern "C" void const* const __imp_swscanf_s = reinterpret_cast<void const*>(swscanf_s);
  2. 用上面的 cpp 文件生成对应的 lib 文件,gcc/g++ 下面,就是后缀 ".a" 的文件
    1. g++ -c legacy_stdio_definitions.cpp -o legacy_stdio_definitions.o
      
      /d/MinGW/mingw64/bin/ar.exe r liblegacy_stdio_definitions.a legacy_stdio_definitions.o

      会在对应目录下生成想要的文件:liblegacy_stdio_definitions.a

  3. 把上面生成的 liblegacy_stdio_definitions.a 文件拷贝到 msys2 mingw64 lib 目录下(D:\msys64\mingw64\lib),和其他的 lib 放在一起
  4. 因为是 libmfx 出现问题,所以修改一下 libmfx 的 pc 文件,多链接上面的 lib
    1. 修改文件:D:\msys64\mingw64\lib\pkgconfig\libmfx.pc
    2. Libs 那一行最后多加上"-llegacy_stdio_definitions"
    3. Libs: -L${libdir} -lmfx -lstdc++ -lole32 -luuid -llegacy_stdio_definitions
  5. 重新 configure 就可以 Pass 了..
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值