Android集成科大讯飞语音识别与语音唤醒简易封装

目录

一、语音唤醒部分

1、首先在科大讯飞官网注册开发者账号

2、配置唤醒词然后下载sdk

3、选择对应功能下载

4、语音唤醒lib包全部复制到工程目录下

5、把语音唤醒词文件复制到工程的assets目录

6、复制对应权限到AndroidManifest.xml中

7、唤醒工具类封装

二、语音识别

1、工具类

2、使用


一、语音唤醒部分

1、首先在科大讯飞官网注册开发者账号

控制台-讯飞开放平台

2、配置唤醒词然后下载sdk

3、选择对应功能下载

4、语音唤醒lib包全部复制到工程目录下

5、把语音唤醒词文件复制到工程的assets目录

6、复制对应权限到AndroidManifest.xml中

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

     <!-- App 需要使用的部分权限 -->
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- 科大讯飞 -->
    <uses-permission
        android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
        tools:ignore="ProtectedPermissions" />
    <uses-permission
        android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
        tools:ignore="ProtectedPermissions" />
    <uses-permission
        android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ProtectedPermissions" />
    <uses-permission
        android:name="android.permission.READ_PHONE_NUMBERS"
        tools:ignore="ProtectedPermissions" />

7、唤醒工具类封装

 其中IflytekAPP_id为科大讯飞平台的应用id


public abstract class WakeUpUtil {
    private static AutoTouch autoTouch = new AutoTouch();//自动点击屏幕
    /**
     * 唤醒的回调
     */
    public abstract void wakeUp(String resultString);

    // Log标签
    private static final String TAG = "WakeUpUtil";

    // 上下文
    private static Context mContext;
    // 语音唤醒对象
    private VoiceWakeuper mIvw;

    //唤醒门限值
    //门限值越高,则要求匹配度越高,才能唤醒
    //值范围:[0,3000]
    //默认值:1450
    private static int curThresh = 1450;

    public WakeUpUtil(Context context) {
        initKedaXun(context);

        mContext = context;
        // 初始化唤醒对象
        mIvw = VoiceWakeuper.createWakeuper(context, null);
        Log.d("initLogData", "===进入唤醒工具类====");

    }

    /**
     * 获取唤醒词功能
     *
     * @return 返回文件位置
     */
    private static String getResource() {
        final String resPath = ResourceUtil.generateResourcePath(mContext, RESOURCE_TYPE.assets, "ivw/" + "cf22564a" + ".jet");
        return resPath;
    }

    /**
     * 唤醒
     */
    public void wake() {
        Log.d("initLogData", "===进入唤醒工具类====");
        // 非空判断,防止因空指针使程序崩溃
        VoiceWakeuper mIvw = VoiceWakeuper.getWakeuper();
        if (mIvw != null) {
            // textView.setText(resultString);
            // 清空参数
            mIvw.setParameter(SpeechConstant.PARAMS, null);
            // 设置唤醒资源路径
            mIvw.setParameter(SpeechConstant.IVW_RES_PATH, getResource());
            // 唤醒门限值,根据资源携带的唤醒词个数按照“id:门限;id:门限”的格式传入
            mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:" + curThresh);
            // 设置唤醒模式
            mIvw.setParameter(SpeechConstant.IVW_SST, "wakeup");
            // 设置持续进行唤醒
            mIvw.setParameter(SpeechConstant.KEEP_ALIVE, "1");
            mIvw.startListening(mWakeuperListener);
            Log.d("initLogData", "====唤醒====");
        } else {
            Log.d("initLogData", "===唤醒未初始化11====");
//            Toast.makeText(mContext, "唤醒未初始化1", Toast.LENGTH_SHORT).show();
        }
    }

    public void stopWake() {
        mIvw = VoiceWakeuper.getWakeuper();
        if (mIvw != null) {
            mIvw.stopListening();
        } else {
            Log.d("initLogData", "===唤醒未初始化222====");
//            Toast.makeText(mContext, "唤醒未初始化2", Toast.LENGTH_SHORT).show();
        }
    }

    String resultString = "";
    private WakeuperListener mWakeuperListener = new WakeuperListener() {

        @Override
        public void onResult(WakeuperResult result) {
            try {

                String text = result.getResultString();
                JSONObject object;
                object = new JSONObject(text);
                StringBuffer buffer = new StringBuffer();
                buffer.append("【RAW】 " + text);
                buffer.append("\n");
                buffer.append("【操作类型】" + object.optString("sst"));
                buffer.append("\n");
                buffer.append("【唤醒词id】" + object.optString("id"));
                buffer.append("\n");
                buffer.append("【得分】" + object.optString("score"));
                buffer.append("\n");
                buffer.append("【前端点】" + object.optString("bos"));
                buffer.append("\n");
                buffer.append("【尾端点】" + object.optString("eos"));
                resultString = buffer.toString();
                stopWake();
                autoTouch.autoClickPos( 0.1, 0.1);

                wakeUp(resultString);
//                MyEventManager.postMsg("" + resultString, "voicesWakeListener");

            } catch (JSONException e) {
                MyEventManager.postMsg("" + "结果解析出错", "voicesWakeListener");
                resultString = "结果解析出错";
                wakeUp(resultString);
                e.printStackTrace();
            }

//            Logger.d("===开始说话==="+resultString);
        }

        @Override
        public void onError(SpeechError error) {

            MyEventManager.postMsg("" + "唤醒出错", "voicesWakeListener");
        }

        @Override
        public void onBeginOfSpeech() {
            Log.d("initLogData", "===唤醒onBeginOfSpeech====");
        }

        @Override
        public void onEvent(int eventType, int isLast, int arg2, Bundle obj) {
//            Log.d("initLogData", "===唤醒onEvent===" + eventType);
        }

        @Override
        public void onVolumeChanged(int i) {
//            Log.d("initLogData", "===开始说话==="+i);
        }
    };

    /**
     * 科大讯飞
     * 语音sdk
     * 初始化
     */
    public void initKedaXun(Context context) {

        // 初始化参数构建
        StringBuffer param = new StringBuffer();
        //IflytekAPP_id为我们申请的Appid
        param.append("appid=" + context.getString(R.string.IflytekAPP_id));
        param.append(",");
        // 设置使用v5+
        param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC);
        SpeechUtility.createUtility(context, param.toString());
        Log.d("initLogData", "===在appacation中初始化=====");
    }

}

使用直接调用即可


    /**
     * 科大讯飞
     * 语音唤醒
     * 对象
     */
    private WakeUpUtil wakeUpUtil;

    private void voiceWake() {

        Log.d("initLogData", "===执行唤醒服务====");
        wakeUpUtil = new WakeUpUtil(this) {
            @Override
            public void wakeUp(String result) {
                MyEventManager.postMsg("" + "唤醒成功", "voicesWakeListener");
                Log.d("initLogData", "====唤醒成功===========" + result);

                // 开启唤醒
                wakeUpUtil.wake();
            }
        };
        wakeUpUtil.wake();

    }

到此语音唤醒已经集成结束,接下来是语音识别。

二、语音识别

1、工具类


/**
 * 科大讯飞
 * 语音识别
 * 工具类
 */
public class KDVoiceRegUtils {

    private SpeechRecognizer mIat;
    private RecognizerListener mRecognizerListener;
    private InitListener mInitListener;

    private StringBuilder result = new StringBuilder();
    // 函数调用返回值
    private int resultCode = 0;

    /**
     * 利用AtomicReference
     */
    private static final AtomicReference<KDVoiceRegUtils> INSTANCE = new AtomicReference<KDVoiceRegUtils>();

    /**
     * 私有化
     */
    private KDVoiceRegUtils() {

    }

    /**
     * 用CAS确保线程安全
     */
    public static final KDVoiceRegUtils getInstance() {
        for (; ; ) {
            KDVoiceRegUtils current = INSTANCE.get();
            if (current != null) {
                return current;
            }
            current = new KDVoiceRegUtils();
            if (INSTANCE.compareAndSet(null, current)) {
                return current;
            }

            Log.d("initLogData", "===科大讯飞实例化===大哥大哥==");
        }
    }

    /**
     * 初始化
     * 监听
     */
    public void initVoiceRecorgnise(Context ct) {

        if (mInitListener != null || mRecognizerListener != null) {
            return;
        }

        mInitListener = new InitListener() {

            @Override
            public void onInit(int code) {
//            Log.e(TAG, "SpeechRecognizer init() code = " + code);
                Log.d("initLogData", "===科大讯飞唤醒初始化===" + code);
                if (code != ErrorCode.SUCCESS) {
//                showToast("初始化失败,错误码:" + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
                }
            }
        };

        //识别监听
        mRecognizerListener = new RecognizerListener() {
            @Override
            public void onBeginOfSpeech() {
                // 此回调表示:sdk内部录音机已经准备好了,用户可以开始语音输入
                Log.d("initLogData", "=====开始说话======");
            }

            @Override
            public void onError(SpeechError error) {
                // Tips:
                // 错误码:10118(您没有说话),可能是录音机权限被禁,需要提示用户打开应用的录音权限。
//                Log.d("initLogData", "====错误说话=====" + error.getPlainDescription(true));
                senVoicesMsg(300, "识别错误 ");//100启动语音识别    200识别成功   300识别错误
                mIat.stopListening();
                hideDialog();
            }

            @Override
            public void onEndOfSpeech() {
                // 此回调表示:检测到了语音的尾端点,已经进入识别过程,不再接受语音输入
                mIat.stopListening();
//                Log.d("initLogData", "=====结束说话======");
                hideDialog();

            }

            @Override
            public void onResult(RecognizerResult results, boolean isLast) {

                String text = parseIatResult(results.getResultString());
//                Log.d("initLogData", "==说话==语音识别结果==initVoice==" + text);
                result.append(text);
                if (!text.trim().isEmpty() && boxDialog != null) {
                    senVoicesMsg(200, "识别成功");//100启动语音识别    200识别成功   300识别错误
                    boxDialog.showTxtContent(result.toString());
                    senVoicesMsg(200, "" + result.toString());
                }

                if (isLast) {
                    result.setLength(0);
                }

            }

            @Override
            public void onVolumeChanged(int volume, byte[] data) {
                //showToast("当前正在说话,音量大小:" + volume);
                if (volume > 0 && boxDialog != null) {
                    boxDialog.showTxtContent("录音中...");
                }
                Log.d("initLogData", "===说话==onVolumeChanged:====" + volume);
            }

            @Override
            public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
                // 以下代码用于获取与云端的会话id,当业务出错时将会话id提供给技术支持人员,可用于查询会话日志,定位出错原因
                // 若使用本地能力,会话id为null
                if (SpeechEvent.EVENT_SESSION_ID == eventType) {
                    String sid = obj.getString(SpeechEvent.KEY_EVENT_SESSION_ID);

                }
            }
        };

        // 初始化识别无UI识别对象
        // 使用SpeechRecognizer对象,可根据回调消息自定义界面;
        mIat = SpeechRecognizer.createRecognizer(ct, mInitListener);
        if (mIat != null) {
            setIatParam();//参数配置
        }

    }

    /**
     * 执行语音
     * 识别
     */
    public void startVoice(Context context) {
        senVoicesMsg(100, "启动语音识别");//100启动语音识别    200识别成功   300识别错误
        if (mIat != null) {
            showDialog(context);
            mIat.startListening(mRecognizerListener);
        }
    }

    /**
     * 科大讯飞
     * 语音识别
     * 参数配置
     */
    private void setIatParam() {

        // 清空参数
        mIat.setParameter(com.iflytek.cloud.SpeechConstant.PARAMS, null);

        // 设置听写引擎
        mIat.setParameter(com.iflytek.cloud.SpeechConstant.ENGINE_TYPE, com.iflytek.cloud.SpeechConstant.TYPE_CLOUD);

        // 设置返回结果格式
        mIat.setParameter(com.iflytek.cloud.SpeechConstant.RESULT_TYPE, "json");

        // 设置语言
        mIat.setParameter(com.iflytek.cloud.SpeechConstant.LANGUAGE, "zh_cn");
        // 设置语言区域
        mIat.setParameter(com.iflytek.cloud.SpeechConstant.ACCENT, "mandarin");

        // 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
        mIat.setParameter(com.iflytek.cloud.SpeechConstant.VAD_BOS, "4000");

        // 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
        mIat.setParameter(com.iflytek.cloud.SpeechConstant.VAD_EOS, "500");

        // 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
        mIat.setParameter(com.iflytek.cloud.SpeechConstant.ASR_PTT, "0");

        Log.d("initLogData", "==语音是被==初始化成功:====");
        // 设置音频保存路径,保存音频格式支持pcm、wav,设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
        // 注:AUDIO_FORMAT参数语记需要更新版本才能生效
//        mIatDialog.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
//        mIatDialog.setParameter(SpeechConstant.ASR_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/MyApplication/" + filename + ".wav");
    }


    /**
     * 语音
     * 识别
     * 解析
     */
    public static String parseIatResult(String json) {

        StringBuffer ret = new StringBuffer();
        try {
            JSONTokener tokener = new JSONTokener(json);
            JSONObject joResult = new JSONObject(tokener);

            JSONArray words = joResult.getJSONArray("ws");
            for (int i = 0; i < words.length(); i++) {
                // 转写结果词,默认使用第一个结果
                JSONArray items = words.getJSONObject(i).getJSONArray("cw");
                JSONObject obj = items.getJSONObject(0);
                ret.append(obj.getString("w"));

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret.toString();
    }

    /**
     * 对话框
     * getApplicationContext()
     */
    private VoiceDialog boxDialog;

    private void showDialog(Context context) {

        View inflate = LayoutInflater.from(context).inflate(R.layout.donghua_layout, null, false);
        boxDialog = new VoiceDialog(context, inflate, VoiceDialog.LocationView.BOTTOM);
        boxDialog.show();
    }

    /**
     * 隐藏
     * 对话框
     */
    private void hideDialog() {

        if (boxDialog != null) {
            boxDialog.dismiss();
        }

    }

    /**
     * 发送语音
     * 识别消息
     *
     * @param code
     * @param conn
     */
    private void senVoicesMsg(int code, String conn) {

        VoiceRecognizeResult voiceRecognizeResult = new VoiceRecognizeResult();
        voiceRecognizeResult.setCode(code);//100启动语音识别    200识别成功   300识别错误
        voiceRecognizeResult.setMsg("" + conn);

        String std = JSON.toJSONString(voiceRecognizeResult);

        MyEventManager.postMsg("" + std, "VoiceRecognizeResult");
    }

    /**
     * 科大讯飞
     * 语音sdk
     * 初始化
     */
    public void initKedaXun(Context context) {

        // 初始化参数构建
        StringBuffer param = new StringBuffer();
        //IflytekAPP_id为我们申请的Appid
        param.append("appid=" + context.getString(R.string.IflytekAPP_id));
        param.append(",");
        // 设置使用v5+
        param.append(SpeechConstant.ENGINE_MODE + "=" + SpeechConstant.MODE_MSC);
        SpeechUtility.createUtility(context, param.toString());
        Log.d("initLogData", "===在appacation中初始化=====");
    }

}

2、使用

        KDVoiceRegUtils.getInstance().initKedaXun(mWXSDKInstance.getContext());
        KDVoiceRegUtils.getInstance().initVoiceRecorgnise(mUniSDKInstance.getContext());//语音识别初始化
        KDVoiceRegUtils.getInstance().startVoice(mUniSDKInstance.getContext());

注意其实代码还可以优化,由于公司业务需要,封装的不怎么彻底,使用者可在此基础上进一步封装。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/236643.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java第二十一章

网络程序设计基础 局域网与互联网 为了实现两台计算机的通信&#xff0c;必须用一个网络线路连接两台计算机。如下图所示 网络协议 1.IP协议 IP是Internet Protocol的简称&#xff0c;是一种网络协议。Internet 网络采用的协议是TCP/IP协议&#xff0c;其全称是Transmissio…

node.js express cors解决跨域

目录 什么是跨域 示例 postman请求 前端请求 cors中间件解决跨域 流程 配置cors参数 什么是跨域 跨域&#xff08;Cross-Origin&#xff09;是指在 Web 开发中&#xff0c;当一个网页的源&#xff08;Origin&#xff09;与另一个网页的源不同时&#xff0c;就发生了跨域…

【USRP】LFTX / LFRX

LFTX/LFRX 设备概述 LFTX 子板利用两个高速运算放大器来允许 0-30 MHz 的传输。该板仅接受实模式信号。LFTX 非常适合 HF 频段的应用&#xff0c;或使用外部前端来上变频和放大中间信号的应用。LFTX 的输出可以独立处理&#xff0c;也可以作为单个 I/Q 对进行处理。 主要特征…

Mac 如何删除文件及文件夹?可以尝试使用终端进行删除

MacOS 是 Mac 电脑采用的操作系统&#xff0c;你知道 Mac 如何删除文件吗&#xff1f;除了直接将文件或者文件夹拖入废纸篓之外&#xff0c;我们还可以采用终端命令的办法去删除文件&#xff0c;本文为大家总结了 Mac 删除文件方法。 为何使用命令行删除文件 在使用 Mac 电脑…

无人零售柜:快捷舒适购物体验

无人零售柜&#xff1a;快捷舒适购物体验 通过无人零售柜和人工智能技术&#xff0c;消费者在购物过程中可以自由选择商品&#xff0c;根据个人需求和喜好查询商品清单。这种自主选择的购物环境能够为消费者提供更加舒适和满意的体验。此外&#xff0c;无人零售柜还具有节约时间…

字符统计[c]

#include<stdio.h> #include<string.h> int main() {int a,b,c;abc0;char s[100];int i0;while(1){i;scanf("%c",&s[i]);if(s[i]?)break;}for(int k1;k<i;k){if(s[k]>48&&s[k]<57){a;//数字}else if((s[k]>65&&s[k]<…

我的 CSDN 三周年创作纪念日:2020-12-12

本人大叔一枚&#xff0c;自1992年接触电脑&#xff0c;持续了30年的业余电脑发烧爱好者&#xff0c;2022年CSDN博客之星Top58&#xff0c;阿里云社区“乘风者计划”专家博主。自某不知名财校毕业后进入国有大行工作至今&#xff0c;先后任职于某分行信息科技部、电子银行部、金…

12月11日作业

完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和密码不匹配&#xf…

Vue 创建一个 Vue 应用

下载安装Node.js Node.Js中文网Node.jsNode.Js中文网 按步骤安装到你想安装的目录即可 安装完毕在控制台输入node 或者node -v测试 将Node.js下载路径改为国内镜像站 npm config set registryhttps://registry.npm.taobao.org/ 查看镜像 npm config get registry 创建项目 …

【C语言】【数据结构】自定义类型:结构体

引言 这是一篇对结构体的详细介绍&#xff0c;这篇文章对结构体声明、结构体的自引用、结构体的初始化、结构体的内存分布和对齐规则、库函数offsetof、以及进行内存对齐的原因、如何修改默认对齐数、结构体传参进行介绍和说明。 ✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&am…

雨云服务器快速搭建Cloudreve网盘网站并挂载雨云对象存储的教程

雨云服务器快速搭建Cloudreve网盘网站并挂载雨云对象存储的教程。本教程的Cloudreve安装就直接用雨云云服务器的预安装APP功能了&#xff0c;然后安装宝塔面板用于反代&#xff0c;如果不需要域名访问功能也可以直接IP端口来访问。 其他建站教程&#xff1a;https://blog.zeru…

C++——继承

目录&#xff1a; 继承的概念及定义 面向对象的三个基本特征&#xff1a;封装、继承、多态。在前面的讲解中封装已经用的很多了&#xff0c;那么接下来的两篇文章就来介绍一下继承和多态。 继承的概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&am…

记录 | xftp远程连接两台windows

1、打开openssh 设置 -> 应用 -> 可选功能 -> 添加功能 -> OpenSSH 客户端&#xff0c;将 ssh 客户端安装将两台电脑的 ssh 开启&#xff0c;cmd 中输入 net start sshd2、配置 win10 账号密码 3、进行 xftp 连接

SSD在AI发展中的关键作用:从高速缓存到数据湖-1

随着人工智能技术的飞速发展&#xff0c;存储在其中发挥着至关重要的作用。特别是在AI训练过程中&#xff0c;存储SSD&#xff08;固态硬盘&#xff09;的高性能和可靠性对于提升训练效率和保证数据安全具有不可替代的作用。 存储SSD在AI发展中的作用和趋势&#xff0c;存储将…

自动化测试之读取配置文件

前言&#xff1a; 在日常自动化测试开发工作中&#xff0c;经常要使用配置文件&#xff0c;进行环境配置&#xff0c;或进行数据驱动等。我们常常把这些文件放置在 resources 目录下&#xff0c;然后通过 getResource、ClassLoader.getResource 和 getResourceAsStream() 等方法…

Spring框架学习:Bean生命周期

目录 SpringBean的生命周期 Bean实例属性填充 三级缓存 常用的Aware接口 Spring IoC容器实例化Bean总结 SpringBean的生命周期 Spring Bean的生命周期是从 Bean 实例化之后&#xff0c;即通过反射创建出对象之后&#xff0c;到Bean成为一个完整对象&#xff0c;最终存储到…

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-3燃烧卡路里-系统分析实例

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-3燃烧卡路里-系统分析实例 1. 数学模型2. 比例控制 Proprotional Control 1. 数学模型 2. 比例控制 Proprotional Control

<JavaEE> 经典设计模式之 -- 单例模式(“饿汉模式”和“懒汉模式”实现单例模式)

目录 一、单例模式概述 二、“饿汉模式”实现单例模式 三、“懒汉模式”实现单例模式 3.1 单线程下的“懒汉模式” 3.2 多线程下的“懒汉模式” 一、单例模式概述 1&#xff09;什么是单例模式&#xff1f; 单例模式是一种设计模式。 单例模式可以保证某个类在程序中只存…

Leetcode 40 组合总和 II

题意理解&#xff1a; 每个数字在每个组合中只能使用 一次 数字可以重复——>难点&#xff08;如何去重&#xff09; 每个组合和target 求组合&#xff0c;对合限制&#xff0c;考虑回溯的方法。——将其抽象为树结构。 树的宽度——分支大小 树的深度——最…

分配栈空间的三种方式(基于适配qemu的FreeRTOS分析)

1、定义全局的数组 定义的全局数组属于bss段&#xff0c;相当于把bss段的一部分作为栈空间&#xff0c;栈空间的大小就是数组的大小如果把栈空间放在bss段&#xff0c;则在bss段清零时会多清零一段地址空间 2、在链接脚本中指定 用链接脚本在所有段的后面增加stack段&#xff…