Rust跨平台编译
❝如果你感觉自己被困住了,焦虑并充满消极情绪,生命出现了停滞,那么治疗方法很简单:「做点什么」。
❞
大家好,我是「柒八九」。一个「专注于前端开发技术/Rust
及AI
应用知识分享」的Coder
前言
之前我们不是写了一篇Rust 赋能前端-开发一款属于你的前端脚手架,从系统架构角度带大家看如何从0到1
构建一个功能完备的前端脚手架。因为,内容包含很多,有些同学说有点消化不了,所以前段时间又写了几篇关于写脚手架可能会用到的技术。
-
如何在Rust中操作JSON -
Rust 写脚手架,Clap你应该知道的二三事
有动手能力强的小伙伴,就开始动手写自己的脚手架了。在他们写完功能后,他们就想要把脚手架编译成二进制文件
,并且通过直接访问或者设置.bashrc
等全局访问。更有甚者,他们还想让自己的朋友使用。在实际操作过程中,就会发生一个问题。
A
同学用Mac
构建了一个工具
,但是她想让B
同学在Windows
环境上使用。此时就会发生问题,我们都知道Windows
和Mac
由于系统架构的不同,在它们环境下编译的二进制文件是「不互通」的。
之前,我们处理的方式就是采用「交叉编译」也就是大家说的跨平台编译。但是呢,由于受文章内容的限制,我们就一带而过,没有过多的去解释。
而有的小伙伴,想了解这方面的知识。所以,今天我们就来聊聊--Rust跨平台编译
好了,天不早了,干点正事哇。
我们能所学到的知识点
❝❞
跨平台编译及其在Rust中的好处 Rust 目标三元组 Rust原生跨平台编译 项目初始化 从Mac到Windows环境的跨平台编译 如何编写特定于平台的代码 其他跨平台解决方案
1. 跨平台编译及其在Rust中的好处
❝❞
跨平台编译
是指能够在一个平台上编译源代码,生成可以在其他平台上运行的可执行文件
或库文件
。它的主要好处是可以显著提高代码的「可移植性」和「复用性」。
在 Rust
中,跨平台编译有以下主要优势:
-
「无需依赖虚拟机」 不同于
Java
和.NET
等需要虚拟机的语言,Rust
编译器「直接将代码编译为机器码」,因此可以直接在目标平台上运行,无需额外的运行时环境
,提高了性能。 -
「静态链接」
Rust
默认静态链接所有依赖库,生成的可执行文件是独立的,无需依赖共享库即可运行,便于部署和分发。 -
「LLVM 支持」
Rust
使用LLVM
作为编译器后端
,LLVM
提供了强大的跨平台支持,能为多种CPU
架构生成高质量的机器码。 -
「标准库的跨平台支持」
Rust
的标准库就设计为跨平台的,它利用了一些跨平台的抽象层,如跨平台系统调用接口,从而使标准库能够在不同操作系统上运行。 -
「编译时单元测试」
Rust
的单元测试在编译时就运行,可以确保在发布时,程序在不同平台上的行为是一致的。
需要说明的是,虽然 Rust
为跨平台编译提供了很好的支持,但由于不同平台的差异,仍然可能需要一些平台特定的代码。不过相比其他语言,Rust
的跨平台编译支持无疑更加方便和高效。
2. Rust 目标三元组
要进行跨平台编译
,我们需要知道我们要构建的平台的「目标三元组」(target triple
)。Rust
使用与LLVM[1]相同的格式。格式为<arch><sub>-<vendor>-<sys>-<env>
。
例如,
-
x86_64-unknown-linux-gnu
代表一个64位Linux
机器 -
x86_64-pc-windows-gnu
代表一个64位的Windows
机器
我们可以运行rustc --print target-list
将打印出Rust
支持的所有目标。这是一段又臭又长的数据信息。
确定我们关心的平台的目标三元组
的两种最佳方法是:
-
在该平台上运行 rustc -vV
,并查找以host:
开头的行——该行的其余部分将是目标三元组
-
或者在 rust platform-support [2]页面中查找
下面一些比较常见的目标三元组
目标三元组名 | 描述 |
---|---|
x86_64-unknown-linux-gnu | 64位Linux(内核3.2+,glibc 2.17+) |
x86_64-pc-windows-gnu | 64位MinGW(Windows 7+) |
x86_64-pc-windows-msvc | 64位MSVC(Windows 7+) |
x86_64-apple-darwin | 64位macOS(10.7+,Lion+) |
aarch64-unknown-linux-gnu | ARM64 Linux(内核4.1,glibc 2.17+) |
aarch64-apple-darwin | ARM64 macOS(11.0+,Big Sur+) |
aarch64-apple-ios | ARM64 iOS |
aarch64-apple-ios-sim | ARM64上的Apple iOS模拟器 |
armv7-linux-androideabi | ARMv7a Android |
3. Rust原生跨平台编译
之前,我们在处理f_cli
的跨平台编译的时候,我们直接是用cargo build --target xx
,这是Rust
内置的方式。
但是呢,这块有一个问题。
要将源代码编译成适配特定平台,我们需要指定一个目标(target
)。这告诉编译器
我们的代码应该编译为哪个平台。因此,我们需要安装相应的 GCC[3]。然后,将目标
添加到 Rust
工具链中。
❝❞
工具链
是一组工具,帮助语言生成功能性的目标代码
。它们可以提供编译器
和链接器
程序,或者额外的库中扩展功能。
下一步是添加链接器。这可以在 Cargo
配置中设置。
❝❞
Rust
编译器「按顺序处理程序中的每个源代码文件」,并检查我们的代码以确保其遵循Rust
语言的规则,并「将我们的源代码转换为称为目标文件的机器语言文件」。编译器
创建一个或多个目标文件之后,另一个名为链接器
的程序将编译器生成的所有目标文件合并为一个「单独的可执行程序」。除了能够链接目标文件外,链接器还能够链接库文件
。库文件是预编译代码的集合,已经被“打包”以供在其他程序中重用。
例如,如果我们想要在Mac
环境下将程序编译成可以在Windows
环境下运行的。就需要执行以下步骤
-
安装目标
mingw-w64
:brew install mingw-w64
-
向
rustup
添加目标:rustup target add x86_64-pc-windows-gnu
-
创建
.cargo/config
-
将以下指令添加到 .cargo/config
中
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc" -
-
最后运行:
cargo build
--target=x86_64-pc-windows-gnu
--verbose
这只是其中一个平台,如果我们的程序想要在多个平台上发布,那就需要做更多的设置。这是一项功能繁杂的工程。
上面的解决方式是可以的,但是今天我们再解释一种更优雅的跨平台编译方式。--cross[4],该crate
曾由Rust嵌入式工作组
维护。
下面,我们就简单来启动一个小项目来讲解一下如何使用cross
进行Rust
的跨平台编译。
4. 项目初始化
又到了我们再熟悉不过的场景了。我们用cargo new
构建一个项目
cargo new cross_compile
然后,我们将main.rs
中内容替换成如下代码:
use current_platform::CURRENT_PLATFORM;
fn main() {
println!("我用的电脑系统是{}!", CURRENT_PLATFORM);
}
我们使用current_platform
crate来探查我们的代码运行的系统信息。
我们可以使用cargo run
来执行对应的代码。因为我的系统是mac
,所以CURRENT_PLATFORM
对应的值为x86_64-apple-darwin
。
我们可以通过rustc -vV
进行查验。
如图所示,通过current_platform
返回的值和rustc
的值是匹配的。大家可以在自己的电脑上运行上面的代码。
5. 从Mac到Windows环境的跨平台编译
通过上文我们已经得知Windows
的目标三元组是x86_64-pc-windows-gnu
那么我们就来开始我们的操作 - 在Mac
中将代码编译到Windows
环境中。
我们使用cross crate
进行操作。
第一步是运行cargo install cross
。这将把Cross
安装到$HOME/.cargo/bin
。
Cross
通过使用一个带有适当工具链的镜像的容器引擎来工作。
由于我们是macOS
,所以我们选择使用Docker
来进行处理。对于Linux
,它建议使用Podman[5],这是一个流行的Docker
替代品。
使用cross
进行交叉编译和cargo
类似。也是需要指定需要编译的target
cross run --target x86_64-pc-windows-gnu
第一次运行时会花费一些时间,因为需要下载并启动适当的容器。
一旦完成,我们就会看到对应的代码输出。(正如上面图中的最后一行)。我们看到cross_compile.exe
正在Windows
环境上运行!
从上面的输出中可以看到,编译后的.exe
文件位于target/x86_64-pc-windows-gnu/debug
。我们可以将其复制到Windows
机器上运行,会显示预期的输出。
执行完上述工作后,我们就可以在Docker
中查看对应的镜像信息。
Cross
甚至支持在其他平台上运行测试!让我们在main.rs
文件中添加一个测试:
mod tests {
use current_platform::{COMPILED_ON, CURRENT_PLATFORM};
#[test]
fn test_compiled_on_equals_current_platform() {
assert_eq!(COMPILED_ON, CURRENT_PLATFORM);
}
}
请注意,这是一个我们期望在Mac
上运行时通过的测试,但当我们跨编译到Windows
并在那里运行时将会失败。
我们在Mac
上运行cargo test
,会得到这样的输出:
要在Windows
上运行测试,语法与运行可执行文件非常相似:
cross test --target x86_64-pc-windows-gnu
大约一分钟后,我们会得到输出:
很遗憾,测试失败了!
❝测试不是在所有平台上都受支持。此外,由于线程问题,测试是顺序运行的,这可能比在本机运行测试要慢得多。
❞
6. 如何编写特定于平台的代码
通常,我们可能希望编写仅在一个平台上运行的代码。Rust
通过cfg属性[6]使这变得简单。
让我们修改我们的程序,添加一个仅在Windows
上打印的消息。事实上,我们甚至不会在非Windows平台
上编译此代码:
use current_platform::CURRENT_PLATFORM;
#[cfg(target_os="windows")]
fn windows_only() {
println!("该方法只在windows环境被触发");
}
fn main() {
println!("我用的电脑系统是{}!", CURRENT_PLATFORM);
#[cfg(target_os="windows")]
{
windows_only();
}
}
在这里,我们将cfg
属性应用于windows_only()
函数,以便它不会在非Windows
平台上编译。但这意味着我们只能在Windows
上调用它,因此我们将相同的cfg
属性应用于调用该函数的代码块。
实际上,我们还可以将属性应用于其他位置,如enum
、struct
和匹配表达式!
在Mac
上运行cargo run
会得到以下输出:
如我们所见,上面的输出没有Windows
特定的消息。但使用cross run --target x86_64-pc-windows-gnu
会得到以下输出:
由于编码的原因,有些汉字没显示全,但是这不是主要的核心点,我们就不做处理了。
Rust
还提供了一种根据平台信息按需应用属性的简单方法
7. 其他跨平台解决方案
上面我们介绍了两种跨平台编译的的方式
-
内置方式 cargo run --target xxx
-
cross run --target xx
可以说,上面的方式属于是N vs N
的。也就是可以在多个平台进行互相编译。
其实还有很多解决的方案。只不过有些解决方案是1 vs N
或者是N vs 1
的。 下面我们就简单的列举几个。
-
cargo-xwin [7]:将 Cargo
项目交叉编译为Windows msvc
目标 -
cargo-zigbuild [8]:使用 zig 作为链接器编译 Cargo 项目。
后记
「分享是一种态度」。
「全文完,既然看到这里了,如果觉得不错,随手点个赞和“在看”吧。」
Reference
LLVM: https://llvm.org/
[2]rust platform-support : https://doc.rust-lang.org/nightly/rustc/platform-support.html
[3]GCC: https://gcc.gnu.org/
[4]cross: https://crates.io/crates/cross
[5]Podman: https://podman.io/
[6]cfg属性: https://doc.rust-lang.org/rust-by-example/attribute/cfg.html
[7]cargo-xwin: https://github.com/rust-cross/cargo-xwin
[8]cargo-zigbuild: https://github.com/rust-cross/cargo-zigbuild
本文由 mdnice 多平台发布
相关文章:
Rust跨平台编译
❝ 如果你感觉自己被困住了,焦虑并充满消极情绪,生命出现了停滞,那么治疗方法很简单:「做点什么」。 ❞ 大家好,我是「柒八九」。一个「专注于前端开发技术/Rust及AI应用知识分享」的Coder 前言 之前我们不是写了一篇R…...
php其他反序列化知识学习
简单总结一下最近学习的,php其他的一些反序列化知识 phar soap session 其他 __wakeup绕过gc绕过异常非公有属性,类名大小写不敏感正则匹配,十六进制绕过关键字检测原生类的利用 phar 基础知识 在 之前学习的反序列化利用中࿰…...
浏览器工作原理与实践--HTTP/1:HTTP性能优化
谈及浏览器中的网络,就避不开HTTP。我们知道HTTP是浏览器中最重要且使用最多的协议,是浏览器和服务器之间的通信语言,也是互联网的基石。而随着浏览器的发展,HTTP为了能适应新的形式也在持续进化,我认为学习HTTP的最佳…...
idea 使用springboot helper 创建springboot项目
Spring Boot Helper 是一个在 IntelliJ IDEA 中用于快速创建 Spring Boot 项目的插件。通过这个插件,开发者可以简化 Spring Boot 项目的创建过程,并快速生成所需的依赖和配置文件。以下是使用 Spring Boot Helper 插件创建 Spring Boot 项目的详细步骤&…...
关于 Amazon DynamoDB 的学习和使用
文章主要针对于博主自己的技术栈,从Unity的角度出发,对于 DynamoDB 的使用。 绿色通道: WS SDK for .NET Version 3 API Reference - AmazonDynamoDBClient Amazon DynamoDB Amazon DynamoDB is a fast, highly scalable, highly available,…...
【fastapi】搭建第一个fastapi后端项目
本篇文章介绍一下fastapi后端项目的搭建。其实没有什么好说的,按照官方教程来即可:https://fastapi.tiangolo.com/zh/ 安装依赖 这也是我觉得python项目的槽点之一。所有依赖都安装在本地,一旦在别人电脑上编写项目就又要安装一遍。很扯淡。…...
Qt/QML编程之路:图片进度条的实现(50)
要实现进度条,而进度条是通过一个图片来展示的,比如逐渐增大的音量,或者逐步增大的车速,通过图片显示的效果肯定更好一些。最直接的想法是通过一个透明的rectagle,把不想让看到的遮住,实际上这种方法不可行。 import QtQuick 2.5 import QtQuick.Window 2.2 import QtGra…...
OOCT WPF_D3D项目报错无法加载依赖项
运行示例项目报错缺少dll,发现运用了这个大老李,通过添加PATH路径也无法解决,看到debug文件夹下面没有其他的依赖项。 通过depneds工具可以看到 OCCTProxy_D3D.dll 缺少依赖项,图中的缺项都是OCCT生成的模块dll所以讲这些dll从..…...
模板方法模式:定义算法骨架的设计策略
在软件开发中,模板方法模式是一种行为型设计模式,它在父类中定义一个操作的算法框架,允许子类在不改变算法结构的情况下重定义算法的某些步骤。这种模式是基于继承的基本原则,通过抽象类达到代码复用的目的。本文将详细介绍模板方…...
es6对于变量的解构赋值(数组解构,对象解构,字符串解构,函数解构等)解析(2024-04-12)
1、数组的解构赋值 [ ] 1.1 数组解构的基本用法 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。本质上叫模型匹配,等号两边的模型相同就可以对应上。 //以前…...
Flutter学习13 - Widget
1、Flutter中常用 Widget 2、StatelessWidget 和 StateFulWidget Flutter 中的 widget 有很多,但主要分两种: StatelessWidget无状态的 widget如果一个 widget 是最终的或不可变的,那么它就是无状态的StatefulWidget有状态的 widget如果一个…...
Django开发一个学生选课系统
在这个选课系统中,分为管理员和学生两种角色。 学生登录系统以后,只能看到选课信息。管理员登录以后,可以看到选课信息和其他的管理系统。 选课界面如下: 学生管理界面如下: 数据分析界面如下: 数据…...
Vue3项目搭建及文件结构
一. Vue3项目搭建 # 安装Vue CLI npm install -g vue/cli# 通过Vue CLI创建项目: vue create my-vue3-project# 当问到你想要使用哪个版本的Vue时,选择Vue3 # 完成配置后,CLI会自动安装依赖并创建项目 # 最后,启动你的Vue3项目cd…...
【机器学习】Logistic与Softmax回归详解
在深入探讨机器学习的核心概念之前,我们首先需要理解机器学习在当今世界的作用。机器学习,作为人工智能的一个重要分支,已经渗透到我们生活的方方面面,从智能推荐系统到自动驾驶汽车,再到医学影像的分析。它能够从大量…...
MATLAB Simulink仿真搭建及代码生成技术—01自定义新建模型模板
MATLAB Simulink仿真搭建及代码生成技术 目录 01-自定义新建模型模板点击运行:显示效果:查看模型设置: 01-自定义新建模型模板 新建模型代码如下: function new_model(modelname) %建立一个名为SmartAss的新的模型并打开 open_…...
【Java8新特性】二、函数式接口
这里写自定义目录标题 一、什么是函数式接口二、自定义函数式接口三、作为参数传递 Lambda 表达式四、四大内置核心函数式接口1、消费形接口2、供给形接口3、函数型接口4、断言形接口 一、什么是函数式接口 只包含一个抽象方法的接口,称为函数式接口。你可以通过 L…...
供应RTC5606H 芯片现货
长期供应各品牌芯片现货: NVP2443I NVP6324 RTC5606H NZ3802-A IRF100B201 IMX290LQR-G STM32F103C8T6TR STM32F103C8T6TR STM32F103CBT7TR TPS3823-33DBVR IMX326 TPS3823-33DBVR LPC55S69**D100 OCP2184QAD DT3001S23E1-30 EMP8734-33…...
洛谷-P1596 [USACO10OCT] Lake Counting S
P1596 [USACO10OCT] Lake Counting S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<bits/stdc.h> using namespace std; const int N110; int m,n; char g[N][N]; bool st[N][N]; //走/没走 int dx[] {-1,-1,-1,0,0,1,1,1}; //八联通 int dy[] {-1,0,1,1,-1,1…...
基于双向长短期神经网络BILSTM的发生概率预测,基于GRU神经网络的发生概率预
目录 背影 摘要 LSTM的基本定义 LSTM实现的步骤 BILSTM神经网络 基于双向长短期神经网络BILSTM的发生概率预测,基于GRU神经网络的发生概率预 完整代码:基于双向长短期神经网络BILSTM的发生概率预测,基于GRU神经网络的发生概率预测资源-CSDN文库 https://download.csdn.net/d…...
对OceanBase中的配置项与系统变量,合法性检查实践
在“OceanBase 配置项&系统变量实现及应用详解”的系列文章中,我们已经对配置项和系统变量的源码进行了解析。当涉及到新增配置项或系统变量时,通常会为其指定一个明确的取值范围或定义一个专门的合法性检查函数。本文将详细阐述在不同情境下&#x…...
YOLOv8绝缘子边缘破损检测系统(可以从图片、视频和摄像头三种方式检测)
可检测图片和视频当中出现的绝缘子和绝缘子边缘是否出现破损,以及自动开启摄像头,进行绝缘子检测。基于最新的YOLO-v8训练的绝缘子检测模型和完整的python代码以及绝缘子的训练数据,下载后即可运行。(效果视频:YOLOv8绝…...
【vim 学习系列文章 18 -- 选中行前后增加两行】
请阅读【嵌入式开发学习必备专栏 之 Vim】 文章目录 选中行前后增加两行1. 定义函数2. 创建快捷键映射3. 保存并重新加载 .vimrc使用方法 重新选中实现步骤 1: 定义函数步骤 2: 绑定快捷键保存并重新加载 .vimrc使用方法 选中行前后增加两行 为了在 Vim 中实现这个功能&#x…...
分布式系统接口限流方案
Git地址:https://gitee.com/deepjava/test-api-limit.git 方案一、 Guava工具包 实现单机版限流 具体代码见git 方案二、Redis lua脚本 实现分布式系统的接口限流 具体代码见git...
Flutter仿Boss-6.底部tab切换
效果 实现 图片资源采用boss包中的动画webp资源。Flutter采用Image加载webp动画。 遇到的问题 问题:Flutter加载webp再次加载无法再次播放动画问题 看如下代码: Image.asset(assets/images/xxx.webp,width: 40.w,height: 30.w, )运行的效果…...
深入理解机器学习:用Python构建您的第一个预测模型
在这个数据驱动的时代,机器学习技术正在成为各行各业的变革力量。无论是金融、医疗、零售还是教育,机器学习都在为业务决策提供支持,优化用户体验,并创造出全新的服务方式。今天,我们将一起走进机器学习的世界…...
redisson与redis集群检测心跳机制原理
redisson与redis集群检测心跳机制原理 1、ClusterConnectionManager.scheduleClusterChangeCheck 创建延时定时调度任务 2、monitorFuture group.schedule(new Runnable() { EventExecutorGroup 是 Netty 中用于管理一组 EventExecutor 的组件,它类似于 EventLoo…...
部署Redis
部署Redis过程简要记录 在家目录创建存放各类软件源码、安装文件、数据、日志、依赖等目录 cd /home/liqiang mkdir sourcecode software app log data lib tmp在 sourcecode 中下载Redis并解压 cd sourcecode wget http://download.redis.io/releases/redis-5.0.4.tar.gz t…...
性能测试-数据库优化二(SQL的优化、数据库拆表、分表分区,读写分离、redis)
数据库优化 explain select 重点: type类型,rows行数,extra SQL的优化 在写on语句时,将数据量小的表放左边,大表写右边where后面的条件尽可能用索引字段,复合索引时,最好按复合索引顺序写wh…...
44.基于SpringBoot + Vue实现的前后端分离-汽车租赁管理系统(项目 + 论文PPT)
项目介绍 本站是一个B/S模式系统,采用SpringBoot Vue框架,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得基于SpringBoot Vue技术的汽车租赁管理系统设计与实现管理工作…...
2024届数字IC秋招-华为机试-数字芯片-笔试真题和答案(五)(含2022年和2023年)
文章目录 前言1、多比特信号A,时钟域clk_a存在从4’d11到4’d12的变化过程中,若时钟域clk_b直接采用D触发器采样,可能采样到数据是2、Bod由1变成0,Arb会如何变化3、减少片外DRAM的访问,而代之以片内SRAM访问,这样可以降低访问功耗,降低片外DRAM,同时加大片内SRAM能节省…...
安宁网站建设 熊掌号/百度高级搜索技巧
10.1文件概念10.1.1文件属性10.1.2文件操作:10.1.3文件类型10.1.4文件结构 10.2访问方法10.3目录结构10.3.1存储结构10.3.2目录概述10.3.3单层结构目录10.3.4双层结构目录10.3.5树结构目录10.3.6无环图目录10.3.7通用图目录 10.4文件系统安装10.5文件共享10.5.1多用…...
两台电脑一台做服务器 网站/爱站网权重查询
虽然微软说asp.net能够匹配各种手机设备,但是手机型号众多,微软收集的手机资料有限,所以导致asp.net对很多手机匹配错误,本来可以支持html的却生成html,本来只支持wml的,缺生成了html导致手机无法浏览&…...
招聘类网站建设/山东seo
这个学校的教务系统从大一用到了大三,给予我本人的感受有好有坏。先说说优点吧 1 方便简洁,当时我们大一还是老宿舍的时候网速特别慢,没有有线用电脑来选课查成绩是特别麻烦,这个平台就非常的快捷。 2 每次选体育,公选…...
怎么做网站的在线客服/百度seo优化网站
使用dbua升级时,需要手工设置CLUSTER_DATABASE参数么? 来源于: Is Manual Setting Of CLUSTER_DATABASE Parameter Required For DBUA Upgrade? (文档 ID 741081.1) 适用于: Oracle Server - Enterprise Edition - Version: 10.…...
如何选择wordpress主机/强强seo博客
2019独角兽企业重金招聘Python工程师标准>>> 什么是Shell脚本? Shell脚本(英语Shellscript)是一种电脑程序与文本文件内容由一连串的shell命令组成经由UnixShell直译其内容后运作被当成是一种脚本语言来设计其运作方式与直译语言相…...
深圳服务网站设计哪家公司好/推广平台哪个效果最好
题库来源:安全生产模拟考试一点通公众号小程序 2022化工自动化控制仪表题库系化工自动化控制仪表试卷新版教材大纲题库!2022年化工自动化控制仪表复训题库及在线模拟考试根据化工自动化控制仪表考试大纲。化工自动化控制仪表考试模拟题通过安全生产模拟…...