搜索
bottom↓
回复: 20

请教库的编写 请大神帮忙讲解下这个文件怎么改

[复制链接]

出0入0汤圆

发表于 2021-12-20 19:43:41 | 显示全部楼层 |阅读模式
本帖最后由 QQ忘了 于 2021-12-20 19:46 编辑

不知道放哪个版块合适   如有不妥请见谅

据说库的结构是C++的规范 请大神帮忙讲解下

如题,

没有系统学过C 然后市面上又是大量的C++ 小白彻底晕了

回来再说库  搞不懂public和private怎么区分

有教程是拿blink程序改编说事  但太简单了说明不了问题  看了没感觉

找了个简单的显示文件ino 把框架罗列在下面  请大神来讲讲课怎样改编为库的形式

先谢了!  



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

贴在下面1楼了,请教怎么改为.h和.cpp   




阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2021-12-20 19:44:10 | 显示全部楼层

uint_8 X=9;
uint_8 Y=8;
uint_8 Z=7;


void init(void);
void mask(char J);

void send(char K);
void draw(char G[8]);




void setup() {

  pinMode(X, OUTPUT);
  pinMode(Y, OUTPUT);
  pinMode(Z, OUTPUT);

  init();
}

void loop() {
...
    draw(0,"start");
...
}





void init(void)  
{
char a1,a2
...
send(a2)
...
}

void mask(char J)
{
...
digitalWrite
...
}

void send(char K)
{
char c1,c2,c3
...
mask(c1)
...
}


void draw(char G[8])
{
int d1,d2
...
send(G[d2]);
}


出715入1076汤圆

发表于 2021-12-20 20:00:36 来自手机 | 显示全部楼层
人生苦短,我放棄 c++ 很多年了

出280入168汤圆

发表于 2021-12-20 20:04:36 | 显示全部楼层
本帖最后由 chunjiu 于 2021-12-20 20:06 编辑

先保证能用,然后技术升级性能,稳定后再将代码变得优雅 ... 不要相信武林玄学,没有靠一本手册就能打通任督二脉、天下无敌的好事情。

任何事情都是踏踏实实一步一步走出来的,马斯克都说火星移民先准备做先驱,而不是先吹技术多牛逼:你们先去,我随后就到。

出200入2554汤圆

发表于 2021-12-20 20:30:56 来自手机 | 显示全部楼层
方向错了,ino文件是用库的,不是让你改编库的。

ino文件就是两个入口的C文件:setup和loop,对应标准C里的唯一入口main.

至于库,有C库也有C++库,本质上都是定义好的数据结构、函数代码。C库只要有几个函数写进文件就行了,C++库更多是在C库的基础上再次封装,方便使用。

至于嫌弃blinker太简单的,建议LZ看看Arduino IDE里的标准库代码,例如EEPROM.h,硬生生封装成了数组一样的用法

出0入0汤圆

 楼主| 发表于 2021-12-21 02:22:36 | 显示全部楼层
dukelec 发表于 2021-12-20 20:00
人生苦短,我放棄 c++ 很多年了


人生总是在折腾     放弃C++   你肯定又奔向另一个坑了









出0入0汤圆

 楼主| 发表于 2021-12-21 02:25:48 | 显示全部楼层
chunjiu 发表于 2021-12-20 20:04
先保证能用,然后技术升级性能,稳定后再将代码变得优雅 ... 不要相信武林玄学,没有靠一本手册就能打通任 ...

有点道理,,  请先教我拆成2个头文件   保证能用的话再慢慢消化  





出0入0汤圆

 楼主| 发表于 2021-12-21 02:32:31 | 显示全部楼层
t3486784401 发表于 2021-12-20 20:30
方向错了,ino文件是用库的,不是让你改编库的。

ino文件就是两个入口的C文件:setup和loop,对应标准C里 ...

晚上在画板子   回复晚了     准确地说是在学习画板子

最近在学习库的结构和编写方法,上面贴的ino是想拆分为自定义库+ino的形式
估计我说的不怎么标准   辞不达意   没学过  小白一个












出200入2554汤圆

发表于 2021-12-21 03:26:16 来自手机 | 显示全部楼层
QQ忘了 发表于 2021-12-21 02:32
晚上在画板子   回复晚了     准确地说是在学习画板子

最近在学习库的结构和编写方法,上 ...

库没啥编写方法,你把定义结构体的语句能放进单独头文件里,就算实现库了。

之后升级为类,并添加类代码(涉及C++语法)就有了。

实际操作看来,LZ分不清private和public区别的话,说明C++零基础,这样一来建议只封装C库,C++库你搞不明白的

出200入2554汤圆

发表于 2021-12-21 05:18:23 | 显示全部楼层
给新人写点东西吧,也算整理一下自己对 C/C++ 在单片机系统里的理解。

【简介】
单片机系统绝大多数使用 C 开发,特定环境下可用 C++ 开发,例如Arduino.

使用 C 追求流程细节均可控,代价是新项目上手难(需要搭建一堆基础函数);
使用 C++ 追求少写代码多办事,代价是老项目维护难(库源码太灵活,找不到断点)。

当单片机的性能可以碾压你的需求时,用 C++ 开发效率很高。


【举例1】
以实现 printf 为例,对比 C 库与 C++ 库的区别。
printf 属于逻辑函数,靠调用更底层的 putchar 实现打印。putchar 一般需要用户来编写,调用端口、串口寄存器实现发送。

a1. 对于 C 库,一般是写好了 printf 的逻辑处理代码,然后预留个 putchar 函数由用户实现。
  如果用户代码里没有定义 putchar,直接就编译不通过。

b1. 对于 C++ 库,同样是写好了 printf 逻辑处理代码,但是会预留个“函数指针”供用户切换。
  更近一步 C++ 会把 printf 代码、putchar 函数指针打包成一个整体,称之为类 class.

至此还看不出 C 库和 C++ 库的差别,现考虑另一种需求:
单片机有好几个串口 UART1, UART2, UART3,我希望 printf 可以通过动态指定的串口出去。

a2. 对于 C 库,基本上要各自编写 UART1_printf, UART2_printf, UART3_printf 版本函数,
  每个函数里调整底层 putchar 数据流走向,再调用公共 printf 实现动态切换。

b2. 对于 C++ 库,由于步骤 b1 封装成了类,直接指定各自 putchar 实例化成数组 ua[3],
  然后直接就能用了: ua[0].printf, ua[1].printf, ua[x].printf

当库需要操作多个同类型硬件时,C++ 的优势就出来了:代码大量复用,改动量远小于 C.


【举例2】
再以坛子里的盖革计为例,单片机有两个串口 UART1,UART2,因而开源的代码里就有:

UART1_Init(), UART2_Init(),
UART1_DeInit(), UART2_DeInit(),


这样重复的函数,每个功能都写两遍。一旦需要改动某函数代码,改了一个忘记另一个是常有的事。
每个串口涉及的用户标志位(例如是否初始化)也统统写两遍,写漏了都算你的 BUG。

如果用 C++ 库,根本不该有这些重复劳动:不需要额外编写,就可以直接调用 UARTx.Init().
用户标志位往哪放? 直接用 C++ 的继承特性,派生一个带用户标志位的新类就可以了,调用起来长这样:

MyUART1.Init();
MyUART1.IsInit= 1;


当然编译出来的 ROM 也会大的感人。


----------------------------------------------------------

之所以只字未提怎么移植/封装 C++ 库,那是因为 LZ 零基础,说了也只会徒增烦恼。
初使用 C++ 库应该是从巨人肩膀往上爬,而不是自己去造个巨人.....

以上个人见解,如有不妥欢迎指正。

出280入168汤圆

发表于 2021-12-21 08:03:18 | 显示全部楼层
  1. // 头文件 my.h

  2. #ifnddef __MY_H_FILE__
  3. #define  __MY_H_FILE__

  4. enum MY_E_VAR = {
  5.   X=9,
  6.   Y=8,
  7.   Z=7,
  8. ;}

  9. void setup();
  10. void loop();

  11. void init(void);
  12. void mask(char J);
  13. void send(char K);
  14. void draw(char G[8]);

  15. #endif



  16. // C 代码文件 my.c

  17. #include "my.h"

  18. void setup() {

  19.   pinMode(X, OUTPUT);
  20.   pinMode(Y, OUTPUT);
  21.   pinMode(Z, OUTPUT);

  22.   init();
  23. }

  24. void loop() {
  25. ...
  26.     draw(0,"start");
  27. ...
  28. }


  29. void init(void)  
  30. {
  31. char a1,a2
  32. ...
  33. send(a2)
  34. ...
  35. }

  36. void mask(char J)
  37. {
  38. ...
  39. digitalWrite
  40. ...
  41. }

  42. void send(char K)
  43. {
  44. char c1,c2,c3
  45. ...
  46. mask(c1)
  47. ...
  48. }


  49. void draw(char G[8])
  50. {
  51. int d1,d2
  52. ...
  53. send(G[d2]);
  54. }
复制代码

出350入477汤圆

发表于 2021-12-21 09:12:34 来自手机 | 显示全部楼层
t3486784401 发表于 2021-12-21 05:18
给新人写点东西吧,也算整理一下自己对 C/C++ 在单片机系统里的理解。

【简介】

用c写库的人,做的好的也应该用c去模拟c++的对象机制。linux核心里面到处这样写,无非就是结构体加函数指针呗。
写个函数叫ComInit,参数是串口结构体的指针,就行了。

出0入0汤圆

 楼主| 发表于 2021-12-21 10:05:54 | 显示全部楼层
t3486784401 发表于 2021-12-21 05:18
给新人写点东西吧,也算整理一下自己对 C/C++ 在单片机系统里的理解。

【简介】

感谢大佬分享   

零基础  不掺假的   看来得去书店泡泡  就是不知道有没有封闭

这里鼓励居家防疫

出0入309汤圆

发表于 2021-12-21 10:08:06 | 显示全部楼层
本帖最后由 iamseer 于 2021-12-21 10:10 编辑

首先先说明一点,Arduino未必要写c++,c的代码也能用,但是必须文件名是cpp和h,不能使用c,否则编译会出错。但是c代码放到cpp文件里完全没问题。

根据LZ的代码,LZ应该还没学会面向对象编程,不过也没问题。
基本思路就是把

void init(void);
void mask(char J);
void send(char K);
void draw(char G[8]);

放到h文件里,对应的函数放到cpp文件里。然后h文件里用类似

#ifndef HEADER_FILE
#define HEADER_FILE

the entire header file file

#endif

的代码包好,防止编译器多次处理出错。

然后在主ino里include你的h文件。编译的时候,ino文件可以调用cpp文件里的函数使用。

至于public和private在写C的时候用不到,c++时才用。另外记得全局变量的有效范围仅在当前文件有效,别的文件要使用的话需要另外extern声明。

符合arduino风格库的写法可以看

https://www.arduino.cc/en/Hacking/LibraryTutorial

补充一点,chunjiu的回答已经基本正确。把setup 和 loop放在ino文件里,然后在ino里#include "my.h" 即可

出0入0汤圆

 楼主| 发表于 2021-12-21 10:16:09 | 显示全部楼层

谢谢啊    很好的示例

对小白来说是个开头  

有些原来的处理函数 怎么拆分到CPP?

用到四个处理函数:
void init(void);
void mask(char J);

void send(char K);
void draw(char G[8]);

根据某些教程的解说貌似只有void mask(char J); 可以列入 private ?

另3个函数  在setup() 和 loop()里都有用到   是不是应该列入 public ?





出280入168汤圆

发表于 2021-12-21 10:23:44 | 显示全部楼层
本帖最后由 chunjiu 于 2021-12-21 10:25 编辑
QQ忘了 发表于 2021-12-21 10:16
谢谢啊    很好的示例

对小白来说是个开头   


这个篇幅太大,建议看一下基础教程:《C++ 大学教程》,

这是经典编程教材,目前好像是第九版,自学和授课都挺实用。

否则的话,现在不搞清楚细节,等换个场景就又不会用了。

PS:

狗洞有链接 https://www.jd.com/jxinfo/7426c6448cebd40b.html

看一下简介,去淘本便宜的。

出0入0汤圆

 楼主| 发表于 2021-12-21 10:28:37 | 显示全部楼层
iamseer 发表于 2021-12-21 10:08
首先先说明一点,Arduino未必要写c++,c的代码也能用,但是必须文件名是cpp和h,不能使用c,否则编译会出错 ...

感谢指导   很有帮助
确实得去找些书啃啃了  

库的构造起来后  在调用的ino文件里  相当于是实例化了一个定义好的对象
这样理解对吗

这种形式的代码比较优雅  所以想努力学好  



出0入309汤圆

发表于 2021-12-21 10:36:44 | 显示全部楼层
QQ忘了 发表于 2021-12-21 10:28
感谢指导   很有帮助
确实得去找些书啃啃了  


https://www.arduino.cc/en/Hacking/LibraryTutorial为例,

Morse morse(13);

这行代码实现了“实例化了一个定义好的对象”

如果要看中文书的话可以买一本人民邮电出版社的 《电子设计与原型开发入门》,章节“8.5 将功能块封装成类” 对这个问题的入门讲得很清楚。个人认为写的很好。

出715入1076汤圆

发表于 2021-12-21 12:49:26 来自手机 | 显示全部楼层
QQ忘了 发表于 2021-12-21 02:22
人生总是在折腾     放弃C++   你肯定又奔向另一个坑了



並沒有,連炒作到火熱的 rust 我都沒有入坑

出0入0汤圆

 楼主| 发表于 2021-12-21 20:13:07 | 显示全部楼层
iamseer 发表于 2021-12-21 10:36
以https://www.arduino.cc/en/Hacking/LibraryTutorial为例,

Morse morse(13);

好的   我去找下这书  

等级低   上午后来无法发言了



出5入14汤圆

发表于 2021-12-22 20:17:06 来自手机 | 显示全部楼层
曾经想入C++的坑,然后什么对象、类、继承、派生之类的概念怎么都没弄明白,,,
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-16 08:29

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表