Linux EXPORT_SYMBOL

Linux驱动中的EXPORT_SYMBOL 一、什么是symbol In a programming language, a symbol is either a variable or a function. Or more generally, we can say, a symbol is a name representing space in the memory, which stores data (variable, for reading and writing) or instructions (function, for ex 阅读详情

一个模块mod1中定义一个函数func1;在另外一个模块mod2中定义一个函数func2,func2调用func1。
在模块mod1中,EXPORT_SYMBOL(func1);
在模块mod2中,extern int func1();
就可以在mod2中调用func1了。

=================================

EXPORT_SYMBOL只出现在2.6内核中,在2.4内核默认的非static 函数和变量都会自动导入到kernel 空间的, 都不用EXPORT_SYMBOL() 做标记的。
2.6就必须用EXPORT_SYMBOL() 来导出来(因为2.6默认不到处所有的符号)。

1、EXPORT_SYMBOL的作用是什么?
EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用,即使用EXPORT_SYMBOL可以将一个函数以符号的方式导出给其他模块使用。
这里要和System.map做一下对比:
System.map 中的是连接时的函数地址。连接完成以后,在2.6内核运行过程中,是不知道哪个符号在哪个地址的。
EXPORT_SYMBOL的符号,是把这些符号和对应的地址保存起来,在内核运行的过程中,可以找到这些符号对应的地址。而模块在加载过程中,其本质就是能动态连接到内核,如果在模块中引用了内核或其它模块的符号,就要EXPORT_SYMBOL这些符号,这样才能找到对应的地址连接。

2、使用方法
   第一、在模块函数定义之后使用EXPORT_SYMBOL(函数名)
   第二、在掉用该函数的模块中使用extern对之声明
   第三、首先加载定义该函数的模块,再加载调用该函数的模块

另外,在编译调用某导出函数的模块时,往往会有WARNING: "****" [**********] undefined!
使用dmesg命令后会看到相同的信息。开始我以为只要有这个错误就不能加载模块,后来上网查了一下,发现这主要是因为在编译连接的时候还没有和内核打交道,当然找不到symbol了,但是由于你生成的是一个内核模块,所以LD不提示error,而是给出一个warning,寄希望于在insmod的时候,内核能够把这个symbol连接上。

 

 

Linux内核头文件提供了一个方便的方法用来管理符号的对模块外部的可见性,因此减少了命名空间的污染(命名空间的名称可能会与内核其他地方定义的名称冲突),并且适当信息隐藏。 如果你的模块需要输出符号给其他模块使用,应当使用下面的宏定义:
EXPORT_SYMBOL(name);
EXPORT_SYMBOL_GPL(name);
这两个宏均用于将给定的符号导出到模块外. _GPL版本的宏定义只能使符号对GPL许可的模块可用。 符号必须在模块文件的全局部分导出,不能在函数中导出,这是因为上述这两个宏将被扩展成一个特殊用途的声明,而该变量必须是全局的。这个变量存储于模块的一个特殊的可执行部分(一个"ELF段" ),在装载时,内核通过这个段来寻找模块导出的变量(感兴趣的读者可以看<linux/module.h>获知更详细的信息)。

【linux内核】EXPORT_SYMBOL_GPL 使用EXPORT_SYMBOL_GPL,可以将一个函数以符号的方式导出给其他GPL许可的模块使用。 阅读详情

相关推荐

RK3568平台(基础篇) EXPORT_SYMBOL的作用

1.在一个模块中使用 EXPORT_SYMBOL(name)。name 表示函数或者变量等符号,它是对全部内核代码公开的,因此在您的内核模块中可以直接调用 name,即使用 EXPORT_SYMBOL 可以将一个函数以符号的方式导出给其他模块使用。2.EXPORT_SYMBOL 的符号,是把这些符号和对应的地址保存起来,在内核运行的过程中,可以找到这些符号对应的地址。而模块在加载过程中,其本质就是能动态连接到内核。

weixin_49303682的博客 744

linux模块导出符号 EXPORT_SYMBOL_GPL EXPORT_SYMBOL

转自http://blog.youkuaiyun.com/lisan04/article/details/4076013 linux2.6的“/prob/kallsyms”文件对应着内核符号表,记录了符号以及符号所在的内存地址。 模块可以使用如下宏导出符号到内核符号表: [c-sharp] view plain copy print? EXPORT_SYMBOL(符号名

qingkongyeyue的博客 6379

Protege入门指南:从下载到本体构建实战

本文是Protege的入门实战指南,详细介绍了如何从官网下载安装这款由斯坦福大学开发的免费本体构建工具,并通过经典的“披萨本体”案例,系统讲解了类、属性、个体和公理四大核心要素。文章还深入解析了Protege的工作界面,并引导读者亲手创建一个简易的“公司人员组织”本体,完成从定义概念、建立关系到逻辑推理的全流程,是知识图谱与本体建模初学者的理想教程。

weixin_29093169的博客 698

Linux的EXPORT_SYMBOL和EXPORT_SYMBOL_GPL的使用和区别

简要说明使用方法: 一个模块mod1中定义一个函数func1;在另外一个模块mod2中定义一个函数func2,func2调用func1。 在模块mod1中,EXPORT_SYMBOL(func1); 在模块mod2中,extern int func1(); 就可以在mod2中调用func1了。 同理EXPORT_SYMBOL_GPL使用相同。 1、EXPORT_SYMBOL的作用是什么? EXPO...

Android/Linux驱动开发传帮带学习,让驱动入门门槛更低! 2万+

MSPM0G3507+逐飞库:5分钟搞定KEIL环境配置与LED闪烁(附常见错误解决)

本文详细介绍了如何使用MSPM0G3507微控制器和逐飞库快速配置KEIL开发环境,并实现LED闪烁功能。从芯片支持包安装、逐飞库工程配置到烧录调试,提供了完整的步骤和常见错误解决方案,帮助开发者5分钟内完成环境搭建。

lambda的博客 1193

告别GIS软件!用R语言ggplot2+ggmapcn绘制出版级世界地图(附5种投影对比图)

本文提供了一份完整的实践指南,教你如何利用R语言及其强大的ggplot2生态系统,结合ggmapcn包,绘制出出版级的世界地图。文章详细对比了五种经典地图投影(如摩尔维德、罗宾森投影)的代码实现与视觉差异,并讲解了如何添加比例尺、指北针等专业元素,最终导出高清PDF,实现从数据分析到专业可视化的全流程代码化操作,彻底告别传统GIS软件。

p5l2m9n4o6q的博客 406

Linux内核的 EXPORT_SYMBOL 和 EXPORT_SYMBOL_GPL 的作用

EXPORT_SYMBOL 和 EXPORT_SYMBOL_GPL 的作用

m0_37383484的博客 6842

MOOS-ivp 实验三 MOOS简介(3)

MOOS-ivp 实验三 MOOS简介(3) 继上一篇文章继续对实验进行记录 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录MOOS-ivp 实验三 MOOS简介(3)六、A Simple Example with pXRelay1.pXRelay基本使用2.pXRelay简单例子3.pXRelay实验七、First Experiments in Modifying MOOS App Code1.下载一个MOOS模板文件2.打开MOOS模板文件总结 六、A Simple E

weixin_44151170的博客 2534

Linux EXPORT_SYMBOL宏详解

Linux 内核中 EXPORT_SYMBOL宏 详解

小立仔 1万+

Yolov8-pose关键点检测:loss优化 | LRM loss困难样本挖掘,提升难样本、遮挡物等检测精度

LRM loss应用到能够大幅提升pose遮挡物性能

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 1713

AI驱动的客户终身价值分析:深入理解公司的收入质量

客户终身价值(Customer Lifetime Value, CLV)是衡量客户在整个生命周期内能为企业带来多少利润的重要指标。传统的CLV计算方法往往过于简化,无法准确反映复杂的客户行为和收入模式。本文旨在介绍如何利用人工智能技术,特别是机器学习方法,构建更精确的CLV预测模型,从而帮助企业深入理解其收入质量。CLV的基本概念和商业意义传统CLV计算方法的局限性基于机器学习的CLV预测方法特征工程和模型选择策略实际应用案例和Python实现首先介绍CLV的基本概念和商业背景。

AI云原生与云计算技术学院 477

Linux 模块导出符号 EXPORT_SYMBOL

概述 EXPORT_SYMBOL 宏的使用时出现在 Linux 2.6 版本之后,在 Linux 2.4 内核中,默认的非 static 函数和变量都会自动导入到内核空间,不需要用 EXPORT_SYMBOL() 做标记的。出于安全考虑,不久之后 Linux 2.6 修改为默认不导出所有的符号,需要导出的符号使用 EXPORT_SYMBOL() 进行标记。 1. EXPORT_SYMBOL 宏的作用 EXPORT_SYMBOL 标签内指定的符号(函数或变量)对全部内核代码公开,不用修改内核代码就可以在内核模

程序员「阿基米东」的编程之旅 3951

open3d将某一时间序列下的彩色图和深度图批量转换成点云(python)

必备条件需要3D相机生成的彩色图及深度图,注意要将深度图与彩色图对齐(一般3D相机自带对齐算子),以及3D相机的彩色图内参(相机自带内参获取功能)。有了此彩色图、对齐后的深度图以及相机内参就能使用open3d生成彩色点云了.

吾名招财的博客 315

linux module (2) - EXPORT_SYMBOL

了解linux EXPORT_SYMBOL 1.Introduction   Generally the modules will never live alone. We need to divide the code into multiple modules for better organization and readability as well as we need to use...

weixin_41028621的博客 798

抖音无水印视频爬虫实战:从抓包分析到批量下载指定用户作品

抖音作为当前最受欢迎的短视频平台,拥有海量的优质内容。很多用户希望备份自己或他人的作品,但抖音官方并未提供批量下载功能,且直接下载的视频带有平台水印。本文将带领大家从零开始,通过抓包分析、设备模拟、请求签名等核心技术,实现一个完整的抖音无水印视频爬虫系统。本文仅供技术学习和个人备份使用,请勿将爬取的内容用于商业用途或侵犯他人版权,爬取频率请控制合理范围内。目录一、前言二、技术栈概览三、准备工作3.1 环境搭建3.2 抓包分析步骤3.3 关键API发现四、核心技术解密4.1 X-Gorgon签名算法。

2201_76125261的博客 844

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Linux中EXPORT_SYMBOL的用法

EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用,即使用EXPORT_SYMBOL可以将一个函数以符号的方式导出给其他模块使用。您还可以手工修改内核源代码来导出另外的函数,用于重新编译并加载新内核后的测试。 Linux symbol export method: [1] If we want export the

sunjiangangok的博客 804

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

linux export_symbol 变量,关于内核中 EXPORT_SYMBOL 导出变量的实例

在内核中,可以通过这两个宏将变量导出,供其他模块使用:EXPORT_SYMBOL();EXPORT_SYMBOL_GPL();实例:hello.c:/***********************************************************************@@ 函数名: hello.c@ 功能: 模块1,生成hello.ko,在这里定义了变量symbol_lxp...

weixin_39631007的博客 326

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

linux模块导出符号EXPORT_SYMBOL与EXPORT_SYMBOL_GPL的区别

模块导出符号 Linux内核头文件提供了一个方便的方法用来管理符号的对模块外部的可见性,因此减少了命名空间的污染(命名空间的名称可能会与内核其他地方定义的名称冲突),并且适当信息隐藏。 如果你的模块需要输出符号给其他模块使用,应当使用下面的宏定义: EXPORT_SYMBOL(name); EXPORT_SYMBOL_GPL(name); 这两个宏均用于将给定的符号导出到模块外. _GPL

jasonlvg的专栏 4264

linux 内核export_symbol变量,Linux内核开发中EXPORT_SYMBOL的使用方法

EXPORT_SYMBOL是Linux内核中一个常见的工具,其作用是讲一个”Symbol”(函数或者变量)导出到内核空间,使得内核的所有代码都可以使用。我们用下面的例子来说明其使用方法。注意:在这篇文章中我假设你已经知道了内核模块开发的基本套路。假设我们创建了两个内核模块mod1和mod2,其中mod1中有一个方法func_exported需要在mod2内调用。Mod1Mod1中的源代码为// m...

weixin_42470145的博客 537

【Linux】内核编程中的EXPORT_SYMBOL()

查看符号导出结果命令: 以EXPORT_SYMBOL(export_symbol_server)为例: $ cat /proc/kallsyms | grep export_symbol_server 一:EXPORT_SYMBOL()宏定义相关定义如下 #define ___PASTE(a, b) a##b #define __PASTE(a, b) ___PASTE(a, b) #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, p

u013416923的博客 2092

linux symbol文件,LINUX EXPORT_SYMBOL_GPL及EXPORT_SYMBOL导出函数

EXPORT_SYMBOL(),这个宏也是将函数导出让所有模块都可以使用,而EXPORT_SYMBOL_GPL()这个宏主要是给有GPL认证的模块使用。2)、EXPORT_SYMBOL标签内定义的函数对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用。3)、EXPORT_SYMBOL(符号名);EXPORT_SYMBOL_GPL(符号名)一)主要作之一: 内核"导出"的符号表,...

weixin_42138716的博客 1050

linux 内核export,linux内核编程中的EXPORT_SYMBOL

linux内核编程中的EXPORT_SYMBOL。EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用,即使用EXPORT_SYMBOL可以将一个函数以符号的方式导出给其他模块使用 。 您还可以手工修改内核源代码来导出另外的函数,用于重新编译并加载新内核后的测试。Linux symbol export method:[1] If we...

weixin_28686915的博客 469

linux EXPORT_SYMBOL

一个模块mod1中定义一个函数func1;在另外一个模块mod2中定义一个函数func2,func2调用func1。 在模块mod1中,EXPORT_SYMBOL(func1); 在模块mod2中,extern int func1(); 就可以在mod2中调用func1了。 ================================= EXPORT_SYMBOL只出现在2.6内核中

brucexu1978的专栏 3445
上一篇: linux 启动过程
下一篇: Linux软连接和硬链接
计算机与认知
博客等级 码龄14年 31粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值