windows下gcc生成dll动态库的问题解决(.c包含了其他的头文件)

发布于:2025-06-20 ⋅ 阅读:(18) ⋅ 点赞:(0)

项目场景:

今天试图将一个.c文件编译成动态库供java调用。第一步gcc -c 生成与位置无关的.o文件成功了。命令:

D:\GmSSL\src>gcc -c -fPIC "tls.c" -o "tls.o" -I "../include"
D:\GmSSL\src>gcc -c -fPIC "../tools/tlcp_client - Copy.c" -o "../tools/tlcp_client - Copy.o" -I"../include"

到了第二部生成.dll动态库时,编译时一直报错。在网上搜了一圈解决方案,全都是加、减、乘、除这些无用的动态库生成教学。好在最终自己摸索解决了,以下是我遇到的问题以及解决方法,希望能帮助到各位。


问题描述

编译报错提示信息:基本都是未定义的引用,然后还有一些文件找不到之类的:

tls.o:tls.c:(.text+0xd11): undefined reference to `sm4_cbc_encrypt'
tls.o:tls.c:(.text+0xd52): undefined reference to `sm4_cbc_encrypt'
tls.o:tls.c:(.text+0xe87): undefined reference to `sm4_cbc_decrypt'
tls.o:tls.c:(.text+0x1841): undefined reference to `sm2_point_to_uncompressed_octets'
tls.o:tls.c:(.text+0x1985): undefined reference to `sm2_point_to_uncompressed_octets'

原因分析和解决方案:

原先我生成.dll的命令是:

gcc  -shared -o "../tools/stlcp_client - Copy.dll" "../tools/tlcp_client - Copy.o" -L"C:\Program Files\GmSSL\lib" -l"gmssl"

1、因为我的C代码包含了国密库的头文件,需要相应的.c文件支持,还调用了Windows Socket API,所以在生成动态库时需要加上相应国密库.c文件生成的.o文件,需要先将其它涉及到的.c文件生成位置无关的.o文件。
2、然后还要链接Windows Socket API所在的静态库。因为考虑到兼容性,我使用的是32位gcc,最终生成的也是32位代码,所以链接到了ws2_32。
然后生成.dll的命令变成:

gcc  -shared -o "../tools/stlcp_client - Copy.dll" "../tools/tlcp_client - Copy.o" "tls.o" -L"C:\Program Files\GmSSL\lib" -l"gmssl" -l"ws2_32"

其它问题

还遇到了一些其它问题:
问题一:找不到链接文件,提示:-lxxx.lib文件找不到
解决方法:确认xxx.lib所在的目录已经添加到系统环境变量中,如果没有添加需要添加到系统环境变量,或者使用-L"xxx.lb所在的文件目录"。windows下的gcc似乎不像linux可以直接识别-lxxx.lib这种编译参数,可以尝试将xxx.lib改成"xxx.lib",-lxxx.lib变成-l"xxx.lib",这个方法不确定。

问题二:提示找不到头文件:
使用-I参数 包含头文件所在子目录的父目录

问题三:.o文件格式不对
解决方法:使用同一编译器生成所有的.o文件。

问题四:不支持的库文件格式
解决方法:确保使用cmake编译生成的库文件,和编译器是统一平台的,譬如32位、64位、ARM64等等,不要库文件是32位却使用64位的gcc来编译链接。

问题五:
错误内容:

d:\GmSSL\src>gcc  -shared -o "../tools/stlcp_client - Copy.dll" "../tools/tlcp_client - Copy.o" "tls.o" -L"C:\Program Files\GmSSL_WIN64\lib" -l"gmssl" -l"ws2_32"
D:/Qt/Tools/mingw1310_64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:\Program Files\GmSSL_WIN64\lib/gmssl.lib when searching for -lgmssl
D:/Qt/Tools/mingw1310_64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:\Program Files\GmSSL_WIN64\lib/gmssl.lib when searching for -lgmssl
D:/Qt/Tools/mingw1310_64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:\Program Files\GmSSL_WIN64\lib\gmssl.lib when searching for -lgmssl
D:/Qt/Tools/mingw1310_64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lgmssl: No such file or directory
D:/Qt/Tools/mingw1310_64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: skipping incompatible C:\Program Files\GmSSL_WIN64\lib/gmssl.lib when searching for -lgmssl
collect2.exe: error: ld returned 1 exit status

解决方法:这是因为我编译gmssl库和编译生成动态库的编译器不一样,gmssl库是32位的,而我编译生成动态库使用的是X86_64位的编译器,将编译生成动态库的编译器改成32位的就好了。需要注意的是编译器的类型最好也要一致,譬如mingw、msvc不要混用,编译库、各个.o文件、以及最后生成动态库都用mingw或者都用msvc。

后续遇到同类会继续补充


网站公告

今日签到

点亮在社区的每一天
去签到