You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C静态库调用外部库函数出现PlaySoundA@12未定义引用错误

问题:静态库调用外部函数时出现undefined reference error to PlaySoundA@12

我开发了一个包含调用外部库函数的C静态库,在构建测试应用时触发undefined reference error to PlaySoundA@12错误,开发流程如下:

步骤1:含外部引用的函数实现

audio_functions.c文件内容:

#include <windows.h>
#include <Mmsystem.h> //For PlaySound() - Winmm.lib is library
#include "audio_functions.h"
uint8_t play_sound(const char *path)
{   
    int psret;
    psret = PlaySound(path, NULL, SND_ASYNC | SND_FILENAME | SND_NODEFAULT | SND_NOSTOP);
    if(psret) { return 1; }
    else { return 0; }
}

该函数用于测试静态库调用外部库的场景。

步骤2:构建静态库

通过bat脚本构建库:

set pname=_ERZ_LIBRARY
set location=C:\MinGW\bin\proj\%pname%

//Creating .o files
//only in audio_functions is an external referance, the other functions works
gcc -c -pedantic %location%\audio_functions\*.c     -o %location%\_AR\audio_functions.o
... more files

cd %location%\_AR\
//Use ar.exe to create archiv from all .o files where created
ar -rcs %location%\BUILD\ERZ_LIBRARY.lib *.o

//Take a look to all functions in library
nm --print-armap %location%\BUILD\ERZ_LIBRARY.lib

nm命令输出显示库中包含_play_sound,且存在未定义的_PlaySoundA@12引用。

步骤3:使用静态库

测试文件test_erz_library.c内容:

#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <mmsystem.h>
#include "C:/MinGW/bin/proj/_ERZ_LIBRARY/ERZ_LIBRARY.h"
int main()
{
    output(blue, NULL, "TEST -- [Version %s]", "1.0.0"); //function from ERZ_LIBRARY that works
    get_version(1); //function from ERZ_LIBRARY that works
    
    play_sound("C:\\MinGW\\bin\\proj\\test_erz_library\\Aramam.wav"); //function from ERZ_LIBRARY that do not work and printing the undefined reference error
}

编译脚本:

set val=test_erz_library
set pname=test_erz_library
gcc C:\MinGW\bin\proj\%pname%\%val%.c -lWinmm -LC:\MinGW\bin\proj\_ERZ_LIBRARY\BUILD -l:ERZ_LIBRARY.lib -o C:\MinGW\bin\proj\%pname%\%val%.exe
C:\MinGW\bin\proj\%pname%\%val%.exe

去除play_sound调用后,其他库函数可正常工作,调用该函数则触发上述错误。


问题原因

GCC链接器遵循依赖库必须放在被依赖的目标文件/库之后的规则。当前编译命令中,-lWinmm放在了测试源文件和静态库之前:链接器处理Winmm.lib时,还未发现需要它的play_sound函数,会直接跳过该库;后续处理ERZ_LIBRARY.lib中的play_sound时,需要PlaySoundA@12,但已无法回溯到之前的Winmm.lib,因此报未定义引用错误。

解决方案

调整编译命令中库的顺序,将-lWinmm移到静态库之后:

set val=test_erz_library
set pname=test_erz_library
gcc C:\MinGW\bin\proj\%pname%\%val%.c -LC:\MinGW\bin\proj\_ERZ_LIBRARY\BUILD -l:ERZ_LIBRARY.lib -lWinmm -o C:\MinGW\bin\proj\%pname%\%val%.exe
C:\MinGW\bin\proj\%pname%\%val%.exe

补充说明

  • 静态库仅保存未定义的外部引用,构建静态库时无需链接Winmm.lib,你的静态库构建流程是正确的。
  • 确认Winmm.lib位于MinGW默认库路径(通常为C:\MinGW\lib),若不在,需额外添加-L<Winmm所在路径>参数。

内容的提问来源于stack exchange,提问作者Erz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 15:40:27