内核模块(传参和依赖)
目录
一、模块传参
二、模块依赖
三、内核空间和用户空间
四、执行流
五、模块编程与应用编程的比较
六、内核接口头文件查询
七、小作业
一、模块传参
module_param(name,type,perm);//将指定的全局变量设置成模块参数
name:全局变量名
type:
使用符号 实际类型 传参方式
bool bool insmod xxx.ko 变量名=0 或 1
invbool bool insmod xxx.ko 变量名=0 或 1
charp char * insmod xxx.ko 变量名="字符串内容"
short short insmod xxx.ko 变量名=数值
int int insmod xxx.ko 变量名=数值
long long insmod xxx.ko 变量名=数值
ushort unsigned short insmod xxx.ko 变量名=数值
uint unsigned int insmod xxx.ko 变量名=数值
ulong unsigned long insmod xxx.ko 变量名=数值
perm:给对应文件 /sys/module/name/parameters/变量名 指定操作权限
(这个name是全局变量名)
#define S_IRWXU 00700
#define S_IRUSR 00400
#define S_IWUSR 00200
#define S_IXUSR 00100
#define S_IRWXG 00070
#define S_IRGRP 00040
#define S_IWGRP 00020
#define S_IXGRP 00010
#define S_IRWXO 00007
#define S_IROTH 00004
#define S_IWOTH 00002 //不要用 编译出错
#define S_IXOTH 00001
(这个文件一般设置成0664.就是perm的位置写0664。忘记什么意思的同学可以看下面同学发的。感觉挺全的)
【Linux】文件的权限_linux文件权限_爽帅_的博客-CSDN博客
module_param_array(name,type,&num,perm);
name、type、perm同module_param,type指数组中元素的类型
&num:存放数组大小变量的地址,可以填NULL(确保传参个数不越界)
传参方式 insmod xxx.ko 数组名=元素值0,元素值1,...元素值num-1
用上面命令可以替换字符串
printk和printf差不多但是不支持浮点型打印
下面就是更改完的程序
#include <linux/module.h>
#include <linux/kernel.h>int gx = 10;
char *gstr = "hello";
int garr[5] = {1,2,3,4,5};module_param(gx, int, 0664);
module_param(gstr, charp, 0664);
module_param_array(garr, int, NULL, 0664);int __init testparam_init(void)
{int i = 0;printk("gx = %d\n", gx);printk("gst = %s\n", gstr);for(i = 0;i < 5;i++){printk("%d ", garr[i]);}printk("\n");return 0;
}
void __exit testparam_exit(void)
{printk("testparam will exit\n");
}
MODULE_LICENSE("GPL");
module_init(testparam_init);
module_exit(testparam_exit);
在makefile里加上我们新的模块
执行make编译
sudo insmod testparam.ko
dmesg
sudo rmmod testparam
sudo dmesg -C
sudo insmod testparam.ko gx=100 gstr="hi" garr=5,6,7,8,9dmesg
可用MODULE_PARAM_DESC宏对每个参数进行作用描述,用法:
`MODULE_PARM_DESC(变量名,字符串常量);`
字符串常量的内容用来描述对应参数的作用
modinfo可查看这些参数的描述信息
二、模块依赖
既然内核模块的代码与其它内核代码共用统一的运行环境,也就是说模块只是存在形式上独立,运行上其实和内核其它源码是一个整体,它们隶属于同一个程序,因此一个模块或内核其它部分源码应该可以使用另一个模块的一些全局特性。
一个模块中这些可以被其它地方使用的名称被称为导出符号,所有导出符号被填在同一个表中这个表被称为符号表。
最常用的可导出全局特性为全局变量和函数
查看符号表的命令:nm
nm查看elf格式的可执行文件或目标文件中包含的符号表,用法:
`nm 文件名` (可以通过man nm查看一些字母含义)
(.o和.ko也是elf格式的文件)
第一列是相对地址
D表示全局变量
T一般指函数
B未初始化的全局变量或静态局部变量
R加了const的全局变量
上面比较常用,下面是man nm查到的全部含义
"A" The symbol's value is absolute, and will not be changed by further linking."B"
"b" The symbol is in the BSS data section. This section typically contains zero-
initialized or uninitialized data, although the exact behavior is system
dependent."C" The symbol is common. Common symbols are uninitialized data. When linking,
multiple common symbols may appear with the same name. If the symbol is
defined anywhere, the common symbols are treated as undefined references."D"
"d" The symbol is in the initialized data section."G"
"g" The symbol is in an initialized data section for small objects. Some object
file formats permit more efficient access to small data objects, such as a
global int variable as opposed to a large global array."i" For PE format files this indicates that the symbol is in a section specific to
the implementation of DLLs. For ELF format files this indicates that the
symbol is an indirect function. This is a GNU extension to the standard set of
ELF symbol types. It indicates a symbol which if referenced by a relocation
does not evaluate to its address, but instead must be invoked at runtime. The
runtime execution will then return the value to be used in the relocation."I" The symbol is an indirect reference to another symbol.
"N" The symbol is a debugging symbol.
"p" The symbols is in a stack unwind section.
"R"
"r" The symbol is in a read only data section."S"
"s" The symbol is in an uninitialized or zero-initialized data section for small
objects."T"
"t" The symbol is in the text (code) section."U" The symbol is undefined.
"u" The symbol is a unique global symbol. This is a GNU extension to the standard
set of ELF symbol bindings. For such a symbol the dynamic linker will make
sure that in the entire process there is just one symbol with this name and
type in use."V"
"v" The symbol is a weak object. When a weak defined symbol is linked with a
normal defined symbol, the normal defined symbol is used with no error. When a
weak undefined symbol is linked and the symbol is not defined, the value of the
weak symbol becomes zero with no error. On some systems, uppercase indicates
that a default value has been specified."W"
"w" The symbol is a weak symbol that has not been specifically tagged as a weak
object symbol. When a weak defined symbol is linked with a normal defined
symbol, the normal defined symbol is used with no error. When a weak undefined
symbol is linked and the symbol is not defined, the value of the symbol is
determined in a system-specific manner without error. On some systems,
uppercase indicates that a default value has been specified."-" The symbol is a stabs symbol in an a.out object file. In this case, the next
values printed are the stabs other field, the stabs desc field, and the stab
type. Stabs symbols are used to hold debugging information."?" The symbol type is unknown, or object file format specific.
· The symbol name.
两个用于导出模块中符号名称的宏:
EXPORT_SYMBOL(函数名或全局变量名)
EXPORT_SYMBOL_GPL(函数名或全局变量名) 需要GPL许可证协议验证
使用导出符号的地方,需要对这些符号进行extern声明后才能使用这些符号
B模块使用了A模块导出的符号,此时称B模块依赖于A模块,则:
1. 编译次序:先编译模块A,再编译模块B,当两个模块源码在不同目录时,需要:i. 先编译导出符号的模块A ii. 拷贝A模块目录中的Module.symvers到B模块目录 iii. 编译使用符号的模块B。否则编译B模块时有符号未定义错误
2. 加载次序:先插入A模块,再插入B模块,否则B模块插入失败
3. 卸载次序:先卸载B模块,在卸载A模块,否则A模块卸载失败
#include <linux/module.h>
#include <linux/kernel.h>int gx = 19;EXPORT_SYMBOL(gx);int __init modulea_init(void)
{printk("In module_a init gx = %d\n", gx);return 0;
}
void __exit modulea_exit(void)
{printk("modulea will exit\n");
}
MODULE_LICENSE("GPL");module_init(modulea_init);
module_exit(modulea_exit);
#include <linux/module.h>
#include <linux/kernel.h>extern int gx;int __init moduleb_init(void)
{printk("In module_b init gx = %d\n", gx);return 0;
}
void __exit moduleb_exit(void)
{printk("moduleb will exit\n");
}
MODULE_LICENSE("GPL");module_init(moduleb_init);
module_exit(moduleb_exit);
一定要先编译提供方在编译使用方
如果先插入B会报错
先插入a在插入b就没错
dmesg
这里有之前插入出错的信息
先移除modulea会出错提示modulea正在被moduleb使用
这样就成功了
如果这两个模块在两个目录下
进入a目录更改makefile然后make编译成功
但是在b中就会失败,因为他缺少a中的全局变量
Linux内核中模块的编译一般分为以下步骤:
- 将每个源文件编译为对应的.o目标文件
- 将每个单独的目标文件链接成模块文件module.o
- 生成对应的module.mod文件,该文件保存链接到模块的所有原始 .o目标文件
- 生成modules.order文件,里面保存的是所有的KO文件
- 从modules.order中查找所有的KO模块
- 使用modpost,为每个KO模块创建module.mod.c文件
- 创建Module.symvers文件,保存模块中通过export导出的符号及其CRC值
- 生成和模块相关的信息(版本魔幻数、模块信息、License、version、alias)
- 外部模块的版本验证
- 通过module.symvers文件,检测模块编译需要的内核符号是否存在
所以我们把符号表粘过去就能正确编译了
补充说明:
内核符号表(直接当文本文件查看)
/proc/kallsyms运行时 /boot/System.map编译后
这台虚拟机可能是升级过有五个版本的符号表
在内核的源码里可以直接用nm命令查看vmLinux
非常的多
也可查看
这里就是符号表,可以在这里查看全部的全局特性
三、内核空间和用户空间
为了彻底解决一个应用程序出错不影响系统和其它app的运行,操作系统给每个app一个独立的假想的地址空间,这个假想的地址空间被称为虚拟地址空间(也叫逻辑地址),操作系统也占用其中固定的一部分,32位Linux的虚拟地址空间大小为4G,并将其划分两部分:
1. 0~3G 用户空间 :每个应用程序只能使用自己的这份虚拟地址空间
2. 3G~4G 内核空间:内核使用的虚拟地址空间,应用程序不能直接使用这份地址空间,但可以通过一些系统调用函数与其中的某些空间进行数据通信
实际内存操作时,需要将虚拟地址映射到实际内存的物理地址,然后才进行实际的内存读写
百度百科-验证
内核启动时。在MMU以前使用的都是真实的物理地址。启动后使用的是虚拟地址(3G~4G)
这些虚拟内存都和实际的物理内存有对应关系。
后面驱动操作内核所以使用的也是3G~4G的虚拟内存
四、执行流
执行流:有开始有结束总体顺序执行的一段独立代码,又被称为代码上下文
计算机系统中的执行流的分类:
执行流:
1. 任务流--任务上下文(都参与CPU时间片轮转,都有任务五状态:就绪态 运行态 睡眠态 僵死态 暂停态)
1. 进程
2. 线程
1. 内核线程:内核创建的线程
2. 应用线程:应用进程创建的线程
(进程线程都是任务,进程是资源占用多的任务。线程是资源占用少的任务)
2. 异常流--异常上下文
1. 中断
2. 其它异常
(任务流的优先级高于异常流,执行时整个时间轮转都会暂停。所以这个程序不能写的太占用时间。要不给用户的感觉会很不好)
应用编程可能涉及到的执行流:
1. 进程
2. 线程
内核编程可能涉及到的执行流:
1. 应用程序自身代码运行在用户空间,处于用户态 ----------------- 用户态app
2. 应用程序正在调用系统调用函数,运行在内核空间,处于内核态,即代码是内核代码但处于应用执行流(即属于一个应用进程或应用线程) ---- 内核态app
3. 一直运行于内核空间,处于内核态,属于内核内的任务上下文 --------- 内核线程
4. 一直运行于内核空间,处于内核态,专门用来处理各种异常 --------- 异常上下文
(当在用户APP中调用了系统函数时。在执行到这个函数时会跳转到内核执行。完了再回来继续执行。虽然使用到了内核空间。但是他还是有个执行流。)
五、模块编程与应用编程的比较
| 不同点 | 内核模块 | 应用程序 |
| API来源 | 不能使用任何库函数 | 各种库函数均可以使用 |
| 运行空间 | 内核空间 | 用户空间 |
| 运行权限 | 特权模式运行 | 非特权模式运行 |
| 编译方式 | 静态编译进内核镜像或编译特殊的ko文件 | elf格式的应用程序可执行文件 |
| 运行方式 | 模块中的函数在需要时被动调用 | 从main开始顺序执行 |
| 入口函数 | init_module | main |
| 退出方式 | cleanup_module | main函数返回或调用exit |
| 浮点支持 | 一般不涉及浮点运算,因此printk不支持浮点数据 | 支持浮点运算,printf可以打印浮点数据 |
| 并发考虑 | 需要考虑多种执行流并发的竞态情况 | 只需考虑多任务并行的竞态 |
| 程序出错 | 可能会导致整个系统崩溃 | 只会让自己崩溃 |
六、内核接口头文件查询
大部分API函数包含的头文件在include/linux目录下,因此:
1. 首先在include/linux 查询指定函数:grep 名称 ./ -r -n
2. 找不到则更大范围的include目录下查询,命令同上
七、小作业
编写3个内核模块A、B、C,A依赖于B,B依赖于C,完成对它们的编译、运行、卸载
这个写错了,最后一个应该是a
有点小瑕疵打印没改
#include <linux/module.h>
#include <linux/kernel.h>extern char char_a;int __init modulea_init(void)
{printk("In module_a init char = %c\n", char_a);return 0;
}
void __exit modulea_exit(void)
{printk("modulea will exit\n");
}
MODULE_LICENSE("GPL");module_init(modulea_init);
module_exit(modulea_exit);
#include <linux/module.h>
#include <linux/kernel.h>extern char char_b;
char char_a = 'a';EXPORT_SYMBOL(char_a);int __init moduleb_init(void)
{printk("In module_b init char = %c\n", char_b);return 0;
}
void __exit moduleb_exit(void)
{printk("moduleb will exit\n");
}
MODULE_LICENSE("GPL");module_init(moduleb_init);
module_exit(moduleb_exit);
#include <linux/module.h>
#include <linux/kernel.h>char char_c = 'c';
char char_b = 'b';
EXPORT_SYMBOL(char_b);int __init modulec_init(void)
{printk("In module_a init char = %c\n", char_c);return 0;
}
void __exit modulec_exit(void)
{printk("modulec will exit\n");
}
MODULE_LICENSE("GPL");module_init(modulec_init);
module_exit(modulec_exit);
相关文章:
内核模块(传参和依赖)
目录 一、模块传参 二、模块依赖 三、内核空间和用户空间 四、执行流 五、模块编程与应用编程的比较 六、内核接口头文件查询 七、小作业 一、模块传参 module_param(name,type,perm);//将指定的全局变量设置成模块参数 name:全局变量名 type: 使用符号 …...
基础篇:03-SpringCloud工程部署启动
目录 1.工程搭建部署 方案一:完整工程导入 方案二:从零开始搭建 1.工程与module创建 2.数据库导入 3.项目启动 3.1 启动并访问user-service 3.2 启动并访问order-service 4.服务远程调用 时序图说明 服务远程调用实现 注入RestTemplate Res…...
二、产品经理——【需求收集】【需求管理】
0. 学习目标 能够理解并描述需求能够收集并管理需求 1. 如何定义需求 1.1. 需求的定义 原始需求:没有经过任何分析,或者没有经过任何额外解读的需求信息 避免日后纠纷,尽量记录一下原始需求!先记录下来,后面再进行分…...
蓝桥杯stm32 USART 串口接收数据
文章代码使用 HAL 库。 文章目录 前言一、创建 CubeMX 工程:二、 中断接收数据 函数:三、串口接收回调函数实验效果四、接收固定长度的数据。五、串口接收 不定长数据。总结前言 上篇文章是 串口的发送数据,这篇文章接着上次的 讲 串口的接受数据。 一、创建 CubeMX 工程:…...
CellularAutomata元胞向量机-9-生命游戏MATLAB代码分享
主程序:%%Conways life with GUI clf % 清除图形clc, clear% %build the GUI %define the plot button plotbuttonuicontrol(style,pushbutton,... string,Run, ... fontsize,12, ... position,[100,400,50,20], ... callback, run1;); %define the stop button era…...
基于Java+Swing+mysql图书管理系统
基于JavaSwingmysql图书管理系统一、系统介绍二、功能展示1.用户登陆、注册2.类别管理--管理员3.图书管理--管理员4.用户管理--管理员5.图书借还情况查看--管理员7.用户主页8.办理还书--用户9.办理还书三、数据库四、其它系统五、获取源码一、系统介绍 该系统实现了 用户: 图书…...
高通IPQ支持串口转RS485
IPQ60xx支持串口转RS485 1. IPQ6018支持串口转RS4851.1 功能需求1.2 原理1.3 实现方法1.4 如何使用RS485?1.5 修改底层串口驱动来进行控制收发状态,上层应用可以直接当成串口来进行操作1. IPQ6018支持串口转RS485 1.1 功能需求 IPQ60xx/IPQ501x/IPQ80xx项目中使用RS485, 需…...
力扣-组合两个表
大家好,我是空空star,本篇带你了解一道简单的力扣sql练习题。 文章目录前言一、题目:175. 组合两个表二、解题1.left join提交SQL运行结果2.right join提交SQL运行结果总结前言 一、题目:175. 组合两个表 表: Person ----------…...
Linux权限概念
目录 Linux权限的概念 什么是权限 如何去操作权限 设置文件所属角色 设置文件属性 umask 粘滞位 Linux权限的概念 首先我们要了解到,在linux下有两种用户:超级用户(root)和普通用户。超级用户的命令提示符是“#”,普通用户的命令提示…...
备战金三银四,这些无数测试前辈们踩过的坑,在面试中,一定要注意这些
你觉得软件测试师这个职位怎么样?大多数人可能会给出答案:“测试?啊,没有技术含量。无非是看需求、业务手册、设计文档,然后点击功能是否实现。问题是测试中的部署和安装是否存在兼容性问题。” 是的,不可否认&#x…...
注解(加与不加的区别)
起因: 在看到这个文章时,对于注解的作用半知半解,由此,写了个例子,验证注解作用 以Override举例 新建一个父类,取名为textone(类名首字母应该大写) 写一个方法: 再新建一个类,继承…...
小众免费的短视频素材库
推荐5个小众但好用的视频素材网站,免费可商用,视频剪辑、自媒体必备~ 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYxMjky 菜鸟图库网素材非常丰富,网站主要还是以设计素材为主,高清视频素材也很多,像风…...
docker-compose安装SonarQube
前言SonarQube 是一个开源的代码分析平台, 用来持续分析和评测项目源代码的质量。 通过SonarQube我们可以检测出项目中重复代码, 潜在bug, 代码规范,安全性漏洞等问题, 并通过SonarQube web UI展示出来。一、docker-compose配置#v…...
《数字经济全景白皮书》金融篇:五十弦翻塞外声,金融热点领域如何实现增长?
易观分析:《数字经济全景白皮书》浓缩了易观分析对于数字经济各行业经验和数据的积累,并结合数字时代企业的实际业务和未来面临的挑战,以及数字技术的创新突破等因素,最终从数字经济发展大势以及各领域案例入手,帮助企…...
微服务门神-Gateway与Sentinel的集成
目录 引言 概述 集成Sentinel 限流维度 网关集成 Route维度 API分组 精准匹配 前缀匹配 正则匹配 自定义限流返回格式 转视频版 引言 书接上篇:微服务门神-Gateway过滤器Filter,讲完了解Gateway过滤器之后,接下来看下Gateway与…...
查找的基本概念
查找表是由同一类型的数据元素(或记录)构成的集合。根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素或记录。关键字:用来标识一个数据元素(或记录)的某个数据项的值。查找算法的评价指标…...
安装v-router出错
一、场景 1、安装v-router npm i --save vue-router 2、报错: npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: sph20.1.0 npm ERR! Found: vue2.7.14 npm ERR! node_modules/vue npm ERR! v…...
2023美赛C题:预测 Wordle 结果
以下内容全部来自本人人工翻译,仅供参考。 文章目录背景要求附件数据文件条目描述纽约时报网站上发布的Wordle指导方针词汇表参考文献服务背景 Wordle是目前纽约时报每天提供的一种受欢迎的谜题。玩家试图通过在六次或更少的机会内猜测一个五个字母的单词来解决谜题…...
minio public桶禁止在直接访问桶位置时列出所有文件url
minio的public桶因为没有限制,所以在直接访问到桶地址的时候会列出桶内所有文件的url,这样很不安全,如何禁止这个功能,可以使用三种方法 1、如果是新版的可以直接设置桶的Access Policy为自定义就好 编辑custom的Policyÿ…...
Python 元组简介
Python 的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。如下实例:实例(Python 2.0)tup1 (physics, chemistry, 1997…...
python gui构造openai api可视化页面
背景:最近chatgpt很火,前几天也想注册体验一下,一顿操作之后,卡在该国家不支持。最后发现自己的代理开在香港,改在漂亮国就行了。虽然有chatgpt可以用,但是小平是自己封装了一个,我不能输。正好…...
服务网格领域的百花齐放,是否存在一个更优解?
作者 lingsamuel,API7.ai 云原生技术专家,Apache APISIX Committer。作者 林志煌,API7.ai 技术工程师,Apache APISIX contributor。 服务网格是一种技术架构,它用于管理微服务系统中各个服务之间的通信,旨…...
Zynq 裸机 PS + PL 双网口实现之 lwip 库文件修改
基于 xilinx vivado 2017.4 库文件 lwip141_v2_0 的修改: 添加对 PHY 芯片 ksz9031 的支持; 添加 SDK 中 LWIP 参数设置对话框 emio_options 选项; 添加 XPAR_GMII2RGMIICON_0N_ETH0_ADDR 和 XPAR_GMII2RGMIICON_0N_ETH1_ADDR 宏配置&#…...
金三银四丨黑蛋老师带你剖析-CTF岗
作者丨黑蛋二进制是个庞大的方向,对应着许许多多方向的岗位,除了之前说过的逆向岗位,漏洞岗位,病毒岗位,还有专门打CTF的岗位,CTF是网络安全领域的一种比赛。普遍来讲,大学生学习网络安全都会参…...
Linux find命令
哈喽,大家好,我是有勇气的牛排(全网同名)🐮 有问题的小伙伴欢迎在文末评论,点赞、收藏是对我最大的支持!!!。 1 介绍 find命令用来查找置顶目录下的文件。任何位于参数…...
vue项目实现会议预约(包含某天的某个时间段和某月的某几天)
一、一天的时间段预约 会议预约有以下操作: 1.点击预约按钮,弹窗最近一周的预约时间点(半小时一个点),预约时间为5:00到24:00; 2.超过当前时间的时间点不允许再预约,已经预约的时间不允许再预约,…...
javacv桌面推送 通过推送和拉取udp组播视频流实现
ffmpeg udp 推流拉流命令单播推流E:/工具/ffmpeg/ffmpeg -f gdigrab -r 23 -i desktop -pkt_size 1316 -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f h264 udp://192.168.1.20:5001拉流ffplay -f h264 udp://192.168.1.20:5001 -fflags nobuffer -nofind_strea…...
2022年直播电商成交额,更是达到了24816亿元的成交额
近年来移动网络覆盖率、网速提升,直播行业不在是陌生的行业,直播也诞生了繁多的领域,游戏直播、户外直播等,当然还有今天的主题“直播带货”。直播带货是线上销售模式的一种,由衷是为了更好的把商品展示给用户观看&…...
【学习总结】2023寒假总结
写在前面时光匆匆,白驹过隙,转眼间寒假就过去了,这次寒假可以算的上是最长的一次假期,经历了从疫情到放开,从患病到阳康,在现实与虚幻的世界中玩耍,在痛苦的数据结构中徘徊,在每次早…...
宝塔搭建实战php源码人才求职管理系统后台端thinkphp源码(一)
大家好啊,我是测评君,欢迎来到web测评。 在开源社区里看到了这一套系统,骑士人才系统SE版,搭建测试了,感觉很不错。能够帮助一些想做招聘平台的朋友降低开发成本,就是要注意,想商业使用的话&…...
邢台企业做网站/关键词优化设计
1.变量 sass中可以定义变量,方便统一修改和维护。 //sass style //----------------------------------- $fontStack: Helvetica, sans-serif; $primaryColor: #333;body {font-family: $fontStack;color: $primaryColor; } //css style //---------------------…...
nginx wordpress 配置/网络营销网站分析
exports和module.exports 在node中,每个模块内部都有一个自己的module对象,而在module中,也有一个对象叫: exports也是一个对象 比如: var module {exports: {foo:bar,add: function(){}} }如果需要对外导出对象,只要把导出的成员挂载到module.exports中,如果每次…...
网站一般要设计几页/企业如何进行网络营销
同学们大家好,我是小伊同学,介绍完API的相关知识,我们继续来学习一些更加复杂的js知识,今天我们先来看一下全局数据读写。在讲解全局数据之前,我们先来回顾一下,之前在讲解小程序架构的时候,我们…...
企业企业网站建/最新新闻播报
【win7下安装node.js错误:roling back action】与【"grunt" 不是内部或外部命令】 解决方法参考文章: (1)【win7下安装node.js错误:roling back action】与【"grunt" 不是内部或外部命令】 解决方法 (2&…...
沈阳做网站 智域/p2p万能搜索引擎
Ant中文手册 下载地址: http://files.cnblogs.com/pengxl/ant_manual.rar 目录: 1. Ant介绍...2. Ant 安装...3. 第一个Ant脚本...4. 整合ant5. Ant进阶...6. Ant常用task.7. 在ant中控制流程(if else )8. 实例分析:9. 如何继…...
成都手机端建站模板/湖南网站seo推广
曾经在qq的日志里写过关于二进制在小型权限系统处理中的作用,这里就又从新整理了一下。 编程中很多时候我们会遇到一种情况,一个对象有多种属性(就好比一个电影内容可以有爱情,动作,悬疑,科幻等)…...