g++编译指定-lusb-1.0/-pthread时的链接类型及符号解析疑惑
关于g++链接libusb、pthreads及动态库符号解析的疑问解答
让我一步步帮你理清这些问题:
1. g++链接器对libusb和pthreads的默认链接方式
g++链接器默认优先采用动态链接,除非你主动指定静态链接的选项(比如添加-static参数,或者直接指定静态库的完整路径/文件名)。从你给出的ldd输出能明确看到,链接的是.so后缀的共享对象文件,说明是动态链接。
2. 带-lusb-1.0和-pthread参数时的链接方式
你的编译命令g++ -pthread -o myprog obj1.o obj2.o -lusb-1.0采用的是动态链接:
-lusb-1.0:链接器会在系统库路径中查找名为libusb-1.0.so的动态库(如果找不到才会尝试静态库libusb-1.0.a),最终链接的是动态库,ldd输出里的libusb-1.0.so.0就是证据。-pthread:这个参数其实是一个复合选项,它会告诉编译器启用线程支持,同时让链接器链接libpthread库,默认也是动态链接,对应ldd输出里的libpthread.so.0。
关于.so文件的加载与符号解析的疑惑
你之前的理解有个误区:.so文件并非只能通过dlopen手动加载,它有两种常见使用方式:
- 编译时动态链接(隐式加载):就是你现在用的这种。编译链接阶段,链接器会把动态库的依赖信息写入可执行文件中。当程序启动时,系统的动态链接器(比如Linux下的
ld-linux.so)会自动查找并加载这些依赖的.so文件,同时自动完成所有符号(函数、变量)的解析和绑定,完全不需要你手动调用dlopen或dlsym,这是动态库最常用的使用方式。 - 运行时手动加载(显式加载):也就是你说的
dlopen+dlsym的方式,这种是程序运行过程中按需加载动态库,通常用于插件化场景,需要开发者手动管理库的加载、符号查找和卸载,灵活性更高,但也更繁琐。
内容的提问来源于stack exchange,提问作者Tony Tannous
相关产品推荐
相关产品推荐

