Linux下如何用GCC编译动态库

动态库dll、静态库 catalog链接静态库示例缺点动态库(共享库) 链接 链接(linking): 将各种代码和数据 收集起来组合成 一个文件 的过程 链接可以发生在: (编译时: .c -> .o) (加载时: 程序 被加载器loader 加载到 存储器) (运行时: 实际运行时) 我们的源文件my.c 经编译后 产生my.obj文件 ' 但是,我们思考一个问题: 我们的my.c里 写的什么内容??' 1, 我们自定义且实现的函数/数据 void my_func(){ xxx } int my_data = 阅读详情

本文主要解决以下几个问题
1 为什么要使用库?
2 库的分类
3 创建自己的库
或许大家对自己初学 Linux时的情形仍记忆尤新吧。如果没有一个能较好的解决依赖关系的包管理器,在Linux下安装软件将是一件及其痛苦的工作。你装a包时,可能会提示你要先装b包,当你费尽心力找到b包时,可能又会提示你要先安装c包。我就曾被这样的事搞的焦头烂额,至今一提起rpm仍心有余悸,头皮发麻。说是一朝被蛇咬,十年怕井绳怕也不为过。
Linux下之所以有这许多的依赖关系,其中一个开发原则真是功不可没。这个原则就是:尽量不重复做别人已经做过的事。换句话说就是尽量充分利用别人的劳动成果。
这就涉及到如何有效的进行代码复用。
1 为什么要使用库?
关于代码复用的途径,一般有两种。
粘贴复制
这是最没有技术含量的一种方案。如果代码小,则工作量还可以忍受,如果代码很庞大,则此法不可取。即便有人原意这样做,但谁又能保证所有的代码都可得到呢?
而库的出现很好的解决了这个问题。
库,是一种封装机制,简单说把所有的源代码编译成目标代码后打成的包。
那么用户怎么能知道这个库提供什么样的接口呢?难道要用nm等工具逐个扫描?
不用担心,库的开发者早以把一切都做好了。除了包含目标代码的库外,www.Linuxidc.com一般还会提供一系列的头文件,头文件中就包含了库的接口。为了让方便用户,再加上一个使用说明就差不多完美了。
2 库的分类
2.1 库的分类
根据链接时期的不同,库又有静态库和动态库之分。
静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行。
有别于静态库,动态库的链接是在程序执行的时候被链接的。所以,即使程序编译完,库仍须保留在系统上,以供程序运行时调用。(TODO:链接动态库时链接阶段到底做了什么)
2.2 静态库和动态库的比较
链接静态库其实从某种意义上来说也是一种粘贴复制,只不过它操作的对象是目标代码而不是源码而已。因为静态库被链接后库就直接嵌入可执行文件中了,这样就带来了两个问题。
首先就是系统空间被浪费了。这是显而易见的,想象一下,如果多个程序链接了同一个库,则每一个生成的可执行文件就都会有一个库的副本,必然会浪费系统空间。
再者,人非圣贤,即使是精心调试的库,也难免会有错。一旦发现了库中有bug,挽救起来就比较麻烦了。必须一一把链接该库的程序找出来,然后重新编译。
而动态库的出现正弥补了静态库的以上弊端。因为动态库是在程序运行时被链接的,所以磁盘上只须保留一份副本,因此节约了磁盘空间。如果发现了bug或要升级也很简单,只要用新的库把原来的替换掉就行了。
那么,是不是静态库就一无是处了呢?
答曰:非也非也。不是有句话么:存在即是合理。静态库既然没有湮没在滔滔的历史长河中,就必然有它的用武之地。想象一下这样的情况:如果你用libpcap库编了一个程序,要给被人运行,而他的系统上没有装pcap库,该怎么解决呢?最简单的办法就是编译该程序时把所有要链接的库都链接它们的静态库,这样,就可以在别人的系统上直接运行该程序了。
所谓有得必有失,正因为动态库在程序运行时被链接,故程序的运行速度和链接静态库的版本相比必然会打折扣。然而瑕不掩瑜,动态库的不足相对于它带来的好处在现今硬件下简直是微不足道的,所以链接程序在链接时一般是优先链接动态库的,除非用-static参数指定链接静态库。
2.3 如何判断一个程序有没有链接动态库?
答案是用file实用程序。
file程序是用来判断文件类型的,在file命令下,所有文件都会原形毕露的。
顺便说一个技巧。有时在 windows下用浏览器下载tar.gz或tar.bz2文件,后缀名会变成奇怪的tar.tar,到Linux有些新手就不知怎么解压了。但 Linux下的文件类型并不受文件后缀名的影响,所以我们可以先用命令file xxx.tar.tar看一下文件类型,然后用tar加适当的参数解压。
另外,还可以借助程序ldd实用程序来判断。
ldd是用来打印目标程序(由命令行参数指定)所链接的所有动态库的信息的,如果目标程序没有链接动态库,则打印“not a dynamic executable”,ldd的用法请参考manpage。
3 创建自己的库
3.1 创建动态库
创建文件hello.c,内容如下:

include

void hello(void)
{
printf(“Hello World\n”);
}
用命令gcc -shared hello.c -o libhello.so编译为动态库。可以看到,当前目录下多了一个文件libhello.so。
[leo@leo test]filelibhello.solibhello.so:ELF32−bitLSBsharedobject,Intel80386,version1(SYSV),notstripped看到了吧,文件类型是sharedobject了。再编辑一个测试文件test.c,内容如下:intmain()hello();return0;这下可以编译了:)[leo@leotest] gcc test.c
/tmp/ccm7w6Mn.o: In function main':
test.c:(.text+0x1d): undefined reference to
hello’
collect2: ld returned 1 exit status
链接时gcc找不到hello函数,编译失败:(。原因是hello在我们自己创建的库中,如果gcc能找到那才教见鬼呢!ok,再接再厉。
[leo@leo test]gcctest.c−lhello/usr/lib/gcc/i686−pc−Linux−gnu/4.0.0/../../../../i686−pc−Linux−gnu/bin/ld:cannotfind−lhellocollect2:ldreturned1exitstatus[leo@leotest] gcc test.c -lhello -L.
[leo@leo test]第一次编译直接编译,gcc默认会链接标准c库,但符号名hello解析不出来,故连接阶段通不过了。现在用gcctest.c−lhello−L.已经编译成功了,默认输出为a.out。现在来试着运行一下:[leo@leotest] ./a.out
./a.out: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory
咦,怎么回事?原来虽然链接时链接器(dynamic linker)找到了动态库libhello.so,但动态加载器(dynamic loader, 一般是/lib/ld-Linux.so.2)却没找到。再来看看ldd的输出:
[leo@leo test]ldda.outLinux−gate.so.1=>(0xffffe000)libhello.so=>notfoundlibc.so.6=>/lib/libc.so.6(0x40034000)/lib/ld−Linux.so.2(0x40000000)果然如此,看到没有,libhello.so=>notfound。Linux为我们提供了两种解决方法:1.可以把当前路径加入/etc/ld.so.conf中然后运行ldconfig,或者以当前路径为参数运行ldconfig(要有root权限才行)。2.把当前路径加入环境变量LDLIBRARYPATH中当然,如果你觉得不会引起混乱的话,可以直接把该库拷入/lib,/usr/lib/等位置(无可避免,这样做也要有权限),这样链接器和加载器就都可以准确的找到该库了。我们采用第二种方法:[leo@leotest] export LD_LIBRARY_PATH=.:LDLIBRARYPATH[leo@leotest] ldd a.out
Linux-gate.so.1 => (0xffffe000)
libhello.so => ./libhello.so (0x4001f000)
libc.so.6 => /lib/libc.so.6 (0x40036000)
/lib/ld-Linux.so.2 (0x40000000)
哈哈,这下ld-Linux.so.2就可以找到libhello.so这个库了。
现在可以直接运行了:
[leo@leo test]./a.outHelloWorld3.2创建静态库仍使用刚才的hello.c和test.c。第一步,生成目标文件。[leo@leotest] gcc -c hello.c
[leo@leo test]lshello.o−l−rw−r–r–1leousers8405月612:48hello.o第二步,把目标文件归档。[leo@leotest] ar r libhello.a hello.o
ar: creating libhello.a
OK,libhello.a就是我们所创建的静态库了,简单吧:)
[leo@leo test]filelibhello.alibhello.a:currentararchive下面一行命令就是教你如何在程序中链接静态库的:[leo@leotest] gcc test.c -lhello -L. -static -o hello.static
我们来用file命令比较一下用动态库和静态库链接的程序的区别:
[leo@leo test]gcctest.c−lhello−L.−ohello.dynamic正如前面所说,链接器默认会链接动态库(这里是libhello.so),所以只要把上个命令中的−static参数去掉就可以了。用file实用程序验证一下是否按我们的要求生成了可执行文件:[leo@leotest] file hello.static hello.dynamic
hello.static: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.6, statically linked, not stripped
hello.dynamic: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.6, dynamically linked (uses shared libs), not stripped
不妨顺便练习一下ldd的用法:
[leo@leo test]lddhello.statichello.dynamichello.static:notadynamicexecutablehello.dynamic:Linux−gate.so.1=>(0xffffe000)libhello.so=>./libhello.so(0x4001f000)libc.so.6=>/lib/libc.so.6(0x40034000)/lib/ld−Linux.so.2(0x40000000)OK,看来没有问题,那就比较一下大小先:[leo@leotest] ls -l hello.[ds]*
-rwxr-xr-x 1 leo users 5911 5月 6 12:54 hello.dynamic
-rwxr-xr-x 1 leo users 628182 5月 6 12:54 hello.static
看到区别了吧,链接静态库的目标程序和链接动态库的程序比起来简直就是一个庞然大物!
这么小的程序,很难看出执行时间的差别,不过为了完整起见,还是看一下time的输出吧:
[leo@leo test]time./hello.staticHelloWorldreal0m0.001suser0m0.000ssys0m0.001s[leo@leotest] time ./hello.dynamic
Hello World
real 0m0.001s
user 0m0.000s
sys 0m0.001s
如果程序比较大的话,应该效果会很明显的。

【Linux】Linux下的gcc编译以及静态库和动态库的制作以及make的使用 一、前言 系统开发人员为了提高项目开发的效率,往往使用成熟库。如何制作静态库和动态库,是软件工程师的基本技能。通过库文件,开发人员可以将自己经常使用的函数封装到库文件中,一方面提供代码的重用,另一方面避免重复劳动,提高项目开发的速度。每一位系统研发工程师,都要学会制作和灵活使用静态库和动态库。 其实就是在Linux里运行c语言,用gcc编译器编译c语言,所谓的库也就是我们之前学c/c++面向对象程序设计时 写的头文件。 二、gcc编译器 1、gcc编译器工作过程: 2、gcc编译器编译过程: 3、gcc 阅读详情

相关推荐

Linux基础|| gcc编译&gcc编译静态库&gcc编译动态库

Linux基础|| gcc编译&gcc编译静态库&gcc编译动态库

weixin_63378697的博客 426

linux中的file命令

file命令用于查看文件类型,今天了解到了,自己动手测了一下,写篇文章记录一下。 [xxx@localhost staticLibrary]$ ls a.out libtest.a libtest.so main.c test.c test.h test.o [xxx@localhost staticLibrary]$ file * a.out: ELF 64-bit LS

1万+

Linux C程序编译链接的过程,gcc/g++,动态库/静态库

源文件编译链接形成可执行程序的过程,gcc/g++,动态库/静态库

TPON的博客 1281

Linux下的库--重要的代码复用机制

Linux下的库--重要的代码复用机制本文主要解决以下几个问题1 为什么要使用库?2 库的分类3 创建自己的库或许大家对自己初学linux时的情形仍记忆尤新吧。如果没有一个能较好的解决依赖关系的包管理器,在linux下安装软件将是一件及其痛苦的工作。你装 a 包时,可能会提示你要先装b包,当你费尽心力找到b包时,可能又会提示你要先安装c包。我就曾被这样的事搞的焦头烂

lemo的专栏 891

终端判断Framewrok是动态库还是静态库

1.打开终端 2.cd到目标Framework文件夹 3.使用file命令 file xxxx(xxxx为Framework文件夹中的执行二进制文件) 你会看到以下信息 动态库输出信息: XXXXSDK: Mach-O universal binary with 4 architectures: [i386:Mach-O dynamically linked shared librar...

ZhongLv_HoneyMoon的博客 1089

hadoop2.2.0 native lib 本地IO库 Linux SuSE 11 X86_64

Hadoop2.2.0 native lib 直接替换掉 2.2.0 发布包里面的nativeIO ,配置好环境变量就可以了 东西虽然小,但是却费了不少功夫,主要是由于本地网络控制,不允许上网。安装各种软件就费了很大劲,软件之间的依赖也很让人头痛, 希望能帮到有需要的兄弟姐妹。。。! 包含的文件: ~/hadoop/hadoop-2.2.0/lib/native> ll 总计 1540 -rw-r--r-- 1 weblogic users 734402 04-15 10:22 libhadoop.a -rwxr-xr-x 1 weblogic users 412856 04-15 10:22 libhadoop.so -rwxr-xr-x 1 weblogic users 412856 04-15 10:22 libhadoop.so.1.0.0 ~/hadoop/hadoop-2.2.0/lib/native> file * libhadoop.a: current ar archive libhadoop.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped libhadoop.so.1.0.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, not stripped 下面是查询的详细OS版本信息 #uname -a Linux F23-B4-E2-B3 2.6.32.12-0.7-default #1 SMP 2010-05-20 11:14:20 +0200 x86_64 x86_64 x86_64 GNU/Linux # lsb_release -a LSB Version: core-2.0-noarch:core-3.2-noarch:core-4.0-noarch:core-2.0-x86_64:core-3.2-x86_64:core-4.0-x86_64:desktop-4.0-amd64:desktop-4.0-noarch:graphics-2.0-amd64:graphics-2.0-noarch:graphics-3.2-amd64:graphics-3.2-noarch:graphics-4.0-amd64:graphics-4.0-noarch Distributor ID: SUSE LINUX Description: SUSE Linux Enterprise Server 11 (x86_64) Release: 11 Codename: n/a weblogic@F23-B4-E2-B1:~> cat /etc/SuSE-release SUSE Linux Enterprise Server 11 (x86_64) VERSION = 11 PATCHLEVEL = 1

linux动态库编译gcc,linux下动态库so文件的一些认识 和 gcc编译的几个阶段

个人创作,欢迎指错。牵扯到ELF格式,gcc编译选项待补,简单实用的说明一下,对Linux下的so文件有个实际性的认识。1.so文件是什么?2.怎么生成以及使用一个so动态库文件?3.地址空间,以及线程安全.4.库的初始化,解析:5.使用我们自己库里的函数替换系统函数://---------------------------------------------------------------...

weixin_42503881的博客 749

RK3568-MIPI屏幕调试实战:LCD初始化时序解析与转换

本文详细解析RK3568平台MIPI屏幕调试中的LCD初始化时序,重点介绍DCS Write与Generic Write数据类型的转换方法,并提供厂家时序到RK格式的实战转换案例。通过理解上电初始化时序的重要性,帮助开发者快速解决屏幕不亮、花屏等常见调试问题,提升RK3568硬件开发效率。

d6e7f8g9h的博客 186

aarch64-linux-gcc安装编译及生成so动态库和调用

并直接选择带有二进制的文件,即在官网入口处选择 binaries 路径,该文件夹下面包含各种版本的已经编译好的 aarch64-linux-gnu-gcc 二进制可执行程序。部分转自:https://blog.youkuaiyun.com/m0_54850825/article/details/124487551。部分转自:https://blog.youkuaiyun.com/qq_42939980/article/details/124150004。x86_64 代表宿主机是64位的,其他的则都为32位的。

weixin_47685129的博客 1万+

别让IO口保护二极管坑了你!实测讲解单片机电流倒灌的三种典型症状与防护

本文深入解析单片机电流倒灌的三大典型症状与防护方案,重点分析STM32等单片机在ADC采样异常、系统假死和通信速率异常中的表现。通过实测数据和电路设计建议,提供从基础二极管隔离到专业隔离器件的分级防护策略,帮助工程师有效预防和解决电流倒灌问题。

weixin_29280219的博客 346

Vmware虚拟机一打开就蓝屏解决方法

Vmware虚拟机一打开就蓝屏解决方法 问题: 一打开Vmware虚拟机就蓝屏,如下图所示: 解决方法1: 启用和关闭windows功能(对话框)——>虚拟机平台(选项打对勾,默认没勾选)——>确定后重启——>再进应该就好了。 解决方法2: ①.查看电脑中的Hyper-V服务是否关闭 1.打开控制面板-程序-程序和功能 2.双击启用或关闭Windows功能 3.把Hyper-V前面的勾去掉 如果后期发下没有反应,或者电脑本身Hyper-V的服务没有打开,可以先打开在关闭,试

m0_55901666的博客 26万+

linux下的静态库和动态库以及gcc常见编译选项

一、linux下的静态库和动态库 linux和windows下都有大量的库,库在本质上就是可执行的二进制代码,可以被操作系统载入内存执行。我们通常将一些通用函数写成函数库,所以库是别人写好的,现有的,成熟的,可以复用的代码,你可以使用但要必须得遵守许可协议。 1.静态库 静态库的文件命名方式是“libxxx.a",库名前加"lib",windows和linux下都是用后缀”.a",“xxx"为静态...

心.跳的博客 1479

[QMT量化交易小白入门]-四十四、年化收益48%的策略要兼容回测和实盘,将实盘改为定时任务的方式

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。

木头大左的博客 1373

在Linux下如何使用GCC编译程序、简单生成静态库及动态库。

在Linux下如何使用GCC编译程序、简单生成 静态库及动态库。<br />   本文适用于Linux下开发初学者。本文初步讲解在Linux下如何使用GCC编译程序、简单生成静态库及动态库。<br /><br /> 一、关于安装。一般系统默认是安装好编译器的,并且网络上有大量资料介绍不同发行版本下的安装问题,本文不再描述。<br /><br /> 二、C编程中的文件后缀名介绍<br />     .a 静态库(打包文件)<br />     .c 未经过预处理的C源码<br />     .

clozxy的专栏 1万+

软考备考:《系统规划与管理师教程》(第2版)第2章——数字ZG与数智化发展

🔴数字化转型的定义:数字化转型是建立在数字化转换、数字化升级基础上,进一步触及组织核心业务,以新建一种业务模式为目标的高层次转型。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 960

【MT7628】固件开发-SDK4320添加MT7612E WiFi驱动操作说明

【MT7628】固件开发-SDK4320添加MT7612E WiFi驱动操作说明

wgl307293845的博客 2079

在Linux下如何使用GCC编译程序、简单生成静态库及动态库

本文适用于Linux下开发初学者。本文初步讲解在Linux下如何使用GCC编译程序、简单生成静态库及动态库。一、关于安装。一般系统默认是安装好编译器的,并且网络上有大量资料介绍不同发行版本下的安装问题,本文不再描述。二、C编程中的文件后缀名介绍    .a 静态库(打包文件)

wens07的专栏 704

KingSCADA实现按钮点击效果

哈喽,你好啊,我是雷工!在做SCADA项目的时候,按钮是不可缺少的功能,但软件自带的按钮太丑,已经无法满足现如今客户对界面美观度的要求。这时候就需要UI小姐姐设计美观大气的SCADA界面,但UI设计的按钮切图放到程序中只是图片素材,当添加了按钮功能时,虽然能实现按钮功能,但没有任何点击效果;当遇到有需要连锁条件才能点击的按钮时,操作员无法区分是有连锁点击了没反应,还是系统界面卡死了导致的没点击成功,这时候有点击效果就能很好的区分这种问题。本篇介绍一种实现按钮点击效果的方法,以下为操作过程。

做有价值的事,积累有价值的笔记! 2765

linux系统下使用gcc/g++编译生成动态库

linux系统下使用命令行开发C/C++程序一般都会用到gcc/g++这个编译工具。大多数学过linux的同学都应该知道关于gcc/g++这个编译工具的简单应用,比方说-c,-o,-S,-E,-g等这些参数。这里我对这些相对比较基础的编译选项就不再赘述了。但我们要说一下如何利用这个工具编译生成动态链接库。

songhuancai的博客 1799

2025年华为杯中国研究生数学建模竞赛C题 围岩裂隙精准识别与三维模型重构 思路+代码

report += f"**位置 {i+1}**: ({loc[0]:.1f}, {loc[1]:.1f}, {loc[2]:.1f})\n"# ==================== 高级U-Net模型 ====================# ==================== 数据预处理与增强 ====================# ==================== 采样方法比较分析 ====================

YOLO 1527

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

linux下gcc编译静态库和动态库

UNIX系统开发-静态库和动态库的建立 UNIX系统及各种软件包为开发人员提供了大量的库文件。但一般情况下这些库文件还不能足以满足用户的所有需求。开发人员大多会根据他们自己的开发、研究要求编写出许多函数。对于这些函数,如果都用在命令行中指定源文件的方法同调用它们的的程序链接起来,虽然也是可以的,但也有一些缺点: 对每一个调用了这些函数的程序,在编译时都需要将这些函数的代码分别重新编译,这实际是

流水mpc 808

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

自学Linux 5—Linux 环境下的编译器之 GCC 编译器工具集详细知识点以及静态库与动态库的使用

一、Linux 下的 GCC 编译器工具集   在 Linux 环境下的编译器之 Vim 安装与基本操作使用 中介绍了如何使用 Linux 环境下的编译器编写程序,并编写了一个 hello.c 的程序。要使编写的程序能够运行,需要进行程序的编译。 Linux 环境下采用的编译器 GCC 来进行对程序的编译。 1. GCC 简介   GCC 是 Linux 下的编译工具集,是 GNU Compile...

Change_Improve的博客 2995

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Qaxwidget文件在linux下,linux下 GCC编译链接静态库&动态库

静态库有时候需要把一组代码编译成一个库,这个库在很多项目中都要用到,例如libc就是这样一个库, 我们在不同的程序中都会用到libc中的库函数(例如printf),也会用到libc中的变量(例如以后 要讲到的environ变量)。本文将介绍怎么创建这样一个库。这些文件的目录结构是:$ tree.|-- main.c`-- stack|-- is_empty.c|-- pop.c|-- push.c...

weixin_35633340的博客 669
上一篇: error while loading shared libraries
下一篇: linux openssl 编程 Server端
pingd
博客等级 码龄15年 60粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值