百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

鸿蒙开发从hello world开始

liebian365 2025-01-02 17:42 23 浏览 0 评论

按照官方教程操作没有坑,我使用的编译环境是 VM12+Ubuntu18.04,并且配置了SSH和Samba。

在Windows下使用VSCODE和ssh,这样的好处是只要虚拟机开机,其他的操作都可以在Windows下进行,并且可以不用在同一台电脑上,有需要可以在云上搭建。

(让人难过的是,我家里用的电脑出现了故障,在公司用的又不能安装VM,所以之后准备换成docker)

下面这个代码树就是拿到开发板后,玩板子的人操作的空间,所有你打算写的代码都在这个。

1、新建文件夹

2、编写业务代码

这段代码引用了三个头文件:

stdio.h:学过C语言的都知道,调用printf的时候就需要使用;

ohos_types.h:将C语言的变量做了重新定义;

ohos_types.h: SYS_RUN这个宏就在这个文件里定义。

在例程的gn文件中提示了头文件的路径:

//utils/native/lite/include

我们主要来看一下关于SYS_RUN的定义:

这段代码需要从下往上看:

LAYER_INITCALL有一个条件编译宏,

  • 定义了LAYER_INIT_SHARED_LIB:

整理得:

这里运用GUN文档中对构造属性的说明 :

就是在这里定义了一个函数BOOT_ run2HelloWorld,在这个函数里调用应用层中的HelloWorld,且这个函数的执行顺序是在main之前,其优先级为702。

  • 没定义LAYER_INIT_SHARED_LIB

整理得

最终得:

InitCall是一个没有参数没有返回值的函数指针类型,#define USED_ATTR __attribute__((used))用来修饰一个变量或者函数,目的是告诉编译器,修饰的这个变量或者函数是被使用的,即使没有使用也不要优化掉:

__attribute__((p(".zinitcall.run2.init")))

用来修饰一个变量或者函数,目的是告诉编译器,修饰的这个变量或者函数要被编译连接到.zinitcall.run2.init这个代码段里,在系统运行后,.zinitcall.run2.init代码段的内容会被逐个执行,就会执行到我们的HelloWorld函数。

那么原宏定义就是定义了一个静态常量__zinitcall_run_HelloWorld,这个常量的类型是个InitCall的指针类型,这个常量的值为HelloWorld,对应一个函数,就是这个函数的地址。并将这个常量编译连接到.zinitcall.run2.init代码段中。

熟悉Linux的都知道,这个是Linux的常规操作,将一系列初始化函数编译链接到一起,运行时候整块取出去执行。

在官方例程的这个脚本文件下:

code-1.0\vendor\hisi\hi3861\hi3861\build\build_tmp\scripts\link.lds

包含下面内容:

刚刚被定义的那个函数指针,编译后就会按照声明的位置,保存在目标代码.zinitcall.run2.init 代码段中.


结合连老师的链接更清晰:

分析 helloworld程序是如何被调用,SYS_RUN做什么事情

补充一下关于宏定义#和##


#:字符串化
##:把宏参数连接在一起,参数在中间两边都需要##
宏定义用#和##的地方宏参数不会再展开,如果需要将传入参数的宏再次展开,需要中间增加一层转换,把所有宏的参数在这层里全部展开,在最下层使用#或者##。

3、业务构建成静态库的BUILD.gn文件,跟刚刚的.c文件在同一个目录下

BUILD.gn文件由三部分内容(目标、源文件、头文件路径)构成:

  • static_library中指定业务模块的编译结果,为静态库文件libmyapp.a,开发者根据实际情况完成填写。
  • sources中指定静态库.a所依赖的.c文件及其路径,若路径中包含"//"则表示绝对路径(此处为代码根路径),若不包含"//"则表示相对路径。
  • include_dirs中指定source所需要依赖的.h文件路径。

4、编写模块BUILD.gn文件,指定需参与构建的特性模块,在app这个目录下,和刚刚新建的那个文件夹(my_first_app)在同一个文件夹下

将"my_first_app:myapp"添加到features字段中,刚刚写的那个代码就能被编译了。

  • my_first_app是相对路径,指向./applications/sample/wifi-iot/app/my_first_app/BUILD.gn。
  • myapp是目标,指向./applications/sample/wifi-iot/app/my_first_app/BUILD.gn中的static_library("myapp")。

编译后进行烧录,效果如下:

相关推荐

python如何对字符串进行操作(python如何对字符串进行操作输出)

1.字符串的创建可通过直接赋值、构造或转义字符来创建字符串。#普通字符串s="Hello,World!"#多行字符串(使用三引号)multi_line_str='''Thisi...

Excel表格中11个常用的字符串函数

今天和大家聊聊常用的字符串函数,在不同的条件下,如何选择字符串函数很关键。下面我为大家列举了11个关于字符串的函数公式。一、EXACT(两个字符串进行结果比较)比较两个字符串是否完全相同(这里是要区分...

详细介绍一下Python中如何对字符串进行操作?

在Python中,字符串做为一种常见的数据处理类型,几乎在每个应用程序中都会被用到。而作为Python中使用最广泛的数据类型Python也是提供了很多强大的方法来支持对于字符串的处理操作。下面我们就来...

Java中你知道几种从字符串中找指定的字符的数量

遇到这样的问题,常规的思路估计就是遍历String,然后逐个对比。下面先看循环遍历循环遍历privatestaticintgetNum(StringoriginStr,Stringtarg...

C语言strcspn函数详解:字符串的“扫雷探测器”

strcspn是C语言标准库中的一个函数,定义在头文件中。它用于计算从字符串的开始到首次出现任何属于指定字符集合的字符之间的字符数量。换句话说,strcspn计算的是主字符串中不包含指定字符集...

如何使用 Python 的 f-string 进行字符串格式化

Python中的字符串格式化曾经有点麻烦。必须在...

java判断字符串中是否包含某个字符

1使用String类的contains()方法contains()方法用于判断字符串中是否包含指定的字符或字符串。语法如下:publicbooleancontains(CharSequence...

Python基础:f-string不同数据类型的格式化选项,终极指南!

上一篇文章我们介绍了4种字符串格式化方法,其中最现代、最直观的方式是f-string,从Python3.6开始引入,而且时不时就增加一些超级优雅的小改进。今天,钢铁老豆想要继续给大家展开介绍不同数据...

Excel查找指定字符串,返回相应的结果

通过下面的函数,可以实现查找指定字符串,若找到返回“有”,若找不到返回“无”。=IF(ISNUMBER(SEARCH("失业",G3)),"有","无")...

一个list中,有b.a.b.c.b.b.写个方法去掉所有b

importjava.util.ArrayList;importjava.util.List;publicclassRemoveBFromStringList{/**...

掌握Python f-string(掌握催眠能力之后的日常生活)

f-string,通常称为格式化字符串文本,是Python3.6中添加的一项强大功能,它提供了一种将表达式包含在字符串文本中的清晰实用的方法。,...

深入了解字符串:定义、转义字符和字符串下标

字符串是编程中常见的数据类型之一,用于表示文本信息。在绝大多数编程语言中,字符串都是由一系列字符组成的序列,可以包含字母、数字、符号以及空格等。字符串的定义:...

100个Java工具类之70:字符串处理工具类StringUtils

StringUtils是常用的工具类,提供大量处理字符串的静态方法。StringUtils主要特点...

Shell中针对字符串的切片,截取,替换,删除,大小写操作

切片返回字符串变量var的长度...

Sqlite - 常规函数 - RTRIM(sqlite命令行工具)

在SQLite中,RTRIM函数是一个用于处理字符串的函数,其主要作用是移除字符串右侧(尾部)的指定字符。如果不指定要移除的字符,默认会移除字符串右侧的空格字符。以下是对RTRIM函数的详细...

取消回复欢迎 发表评论: