ToB企服应用市场:ToB评测及商务社交产业平台

标题: Arduino平台软硬件原理及使用——开源库的使用 [打印本页]

作者: 李优秀    时间: 2024-10-15 23:56
标题: Arduino平台软硬件原理及使用——开源库的使用
文章目录:
一、库文件的下载及导入
二、库文件源代码分析
三、库文件应用举例
  一、库文件的下载及导入


有关arduino开源库的导入有两种方案:
1.第一种方案需要借助arduino.cc网站来举行查询下载,然后在Arduino软件中举行导入。
2.第二种方案则只需要使用较新版本的Arduino软件(2.2版本之后),在软件中可以直接搜索并导入开源库。
1.在Arduino.cc举行导入库

首先在网页地点框直接输入arduino.cc便可进入网站:

然后点击上方【DOCUMENTATION】选项:

在此页面点击左侧【Libraries】选项,便可进入官方收录的库文件页面:

选择要用的库文件的类目,这里以【display】为例:

然后点击具体的库文件,以【LiquidCrystal】为例:

进入库文件下载目录后,直接点击要用的版本号即可直接下载。
下载完成后如果不是压缩包,最好压缩成zip文件:

末了打开Arduino软件,选择【项目】-【导入库】-【添加.ZIP库】然后选择对应的zip文件即可导入乐成。
2.使用Arduino软件导入库

上述方案较为复杂,所以建议使用较新版本的Arduino软件直接导入库:

在此版本的软件中直接点选左侧的“册本”样式的图标(其表示为库文件),然后直接在搜索框查找要使用的库文件名,选择对应库文件及版本点击安装即可。
这种方案则最为简洁,当然有些时间要使用的库在软件中查询不到,此时就需要接纳第一种方案举行导入。
2、库文件源代码分析


如上图所示,一般库文件中会有如上几个文件(会存在些许不同)。
1.示例程序的使用

example文件即为【示例】,这里面会有开源文件贡献者编写的几个示例程序,用于资助学习者理解库的使用:

当然只要将库文件导入过Arduino中,也可以在Arduino软件中打开相应的示例程序:

2.【.h文件】及【.cpp】文件分析

在【src】文件夹中存在以下两个文件:
【.h】后缀我们称之为头文件,【.cpp】后缀我们称之为源文件

头文件通常包含类声明函数原型宏定义全局变量声明等。它们的目的是提供一种方式来共享代码,并确保在多个源文件中使用一致的声明:
  1. /*
  2.   HCSR04 - Library for arduino, for HC-SR04 ultrasonic distance sensor.
  3.   Created by Dirk Sarodnick, 2020.
  4. */
  5. #ifndef HCSR04_H
  6. #define HCSR04_H
  7. #include "Arduino.h"
  8. #define HCSR04_INVALID_RESULT  -1;
  9. #define HCSR04_NO_TRIGGER      -2;
  10. #define HCSR04_NO_ECHO         -3;
  11. class HCSR04Sensor {
  12.         public:
  13.                 HCSR04Sensor();
  14.                 ~HCSR04Sensor();
  15.                 typedef enum eUltraSonicUnlock {
  16.                         unlockSkip = 0,
  17.                         unlockMaybe = 1,
  18.                         unlockForced = 2
  19.                 } eUltraSonicUnlock_t;
  20.                
  21.                 void begin(uint8_t triggerPin, uint8_t echoPin) { begin(triggerPin, new uint8_t[1]{ echoPin }, 1); }
  22.                 void begin(uint8_t triggerPin, uint8_t* echoPins, uint8_t echoCount) { begin(triggerPin, echoPins, echoCount, 100000, eUltraSonicUnlock_t::unlockSkip); }
  23.                 void begin(uint8_t triggerPin, uint8_t echoPin, uint32_t timeout, eUltraSonicUnlock_t unlock) { begin(triggerPin, new uint8_t[1]{ echoPin }, 1, timeout, unlock); }
  24.                 void begin(uint8_t triggerPin, uint8_t* echoPins, uint8_t echoCount, uint32_t timeout, eUltraSonicUnlock_t unlock) { begin(triggerPin, echoPins, echoCount, timeout, 10, 10, unlock); }
  25.                 void begin(uint8_t triggerPin, uint8_t* echoPins, uint8_t echoCount, uint32_t timeout, uint16_t triggerTime, uint16_t triggerWait, eUltraSonicUnlock_t unlock);
  26.                 void end();
  27.                
  28.                 long* measureMicroseconds() { measureMicroseconds(lastMicroseconds); return lastMicroseconds; }
  29.                 void measureMicroseconds(long* results);
  30.                 double* measureDistanceMm() { measureDistanceMm(defaultTemperature, lastDistances); return lastDistances; }
  31.                 void measureDistanceMm(double* results) { measureDistanceMm(defaultTemperature, results == NULL ? lastDistances : results); }
  32.                 double* measureDistanceMm(float temperature) { measureDistanceMm(temperature, lastDistances); return lastDistances; }
  33.                 void measureDistanceMm(float temperature, double* results);
  34.                 double* measureDistanceCm() { measureDistanceCm(defaultTemperature, lastDistances); return lastDistances; }
  35.                 void measureDistanceCm(double* results) { measureDistanceCm(defaultTemperature, results == NULL ? lastDistances : results); }
  36.                 double* measureDistanceCm(float temperature) { measureDistanceCm(temperature, lastDistances); return lastDistances; }
  37.                 void measureDistanceCm(float temperature, double* results);
  38.                 double* measureDistanceIn() { measureDistanceIn(defaultTemperature, lastDistances); return lastDistances; }
  39.                 void measureDistanceIn(double* results) { measureDistanceIn(defaultTemperature, results == NULL ? lastDistances : results); }
  40.                 double* measureDistanceIn(float temperature) { measureDistanceIn(temperature, lastDistances); return lastDistances; }
  41.                 void measureDistanceIn(float temperature, double* results);
  42.                
  43.                 static void triggerInterrupt0(void);
  44.                 static void triggerInterrupt1(void);
  45.                 static void triggerInterrupt2(void);
  46.                 static void triggerInterrupt3(void);
  47.                 static void triggerInterrupt4(void);
  48.                 static void triggerInterrupt5(void);
  49.                 static void triggerInterrupt6(void);
  50.                 static void triggerInterrupt7(void);
  51.                 static void triggerInterrupt8(void);
  52.                 static void triggerInterrupt9(void);
  53.                
  54.                 static void echoInterrupt0(void);
  55.                 static void echoInterrupt1(void);
  56.                 static void echoInterrupt2(void);
  57.                 static void echoInterrupt3(void);
  58.                 static void echoInterrupt4(void);
  59.                 static void echoInterrupt5(void);
  60.                 static void echoInterrupt6(void);
  61.                 static void echoInterrupt7(void);
  62.                 static void echoInterrupt8(void);
  63.                 static void echoInterrupt9(void);
  64.        
  65.         private:
  66.                 float defaultTemperature = 19.307;
  67.                 long* lastMicroseconds;
  68.                 double* lastDistances;
  69.                 uint32_t timeout;
  70.                 uint16_t triggerTime = 10; // HC-SR04 needs at least 10�s trigger. Others may need longer trigger pulses.
  71.                 uint16_t triggerWait = 10; // HC-SR04 sends its signal about 200�s. We only wait a small amount to reduce interference, but to not miss anything on slower clock speeds.
  72.                 volatile uint8_t triggerPin;
  73.                 volatile unsigned long* volatile triggerTimes;
  74.                
  75.                 uint8_t echoCount;
  76.                 volatile int16_t* volatile echoStages;
  77.                 volatile int16_t* volatile echoInts;
  78.                 volatile int16_t* volatile echoPorts;
  79.                 volatile unsigned long* volatile echoTimes;
  80.                
  81.                 void triggerInterrupt(uint8_t);
  82.                 void echoInterrupt(uint8_t);
  83.                 void unlockSensors(eUltraSonicUnlock_t, uint8_t*);
  84. };
  85. extern HCSR04Sensor HCSR04;
  86. #endif // HCSR04_H
复制代码
源文件包含了实现代码,即函数和方法的定义。它们通常包含与头文件对应的实现:
  1. /*
  2.   HCSR04 - Library for arduino, for HC-SR04 ultrasonic distance sensor.
  3.   Created by Dirk Sarodnick, 2020.
  4. */
  5. #include "Arduino.h"
  6. #include "HCSR04.h"
  7. HCSR04Sensor::HCSR04Sensor() {}
  8. HCSR04Sensor::~HCSR04Sensor() { this->end(); }
  9. void HCSR04Sensor::begin(uint8_t triggerPin, uint8_t* echoPins, uint8_t echoCount, uint32_t timeout, uint16_t triggerTime, uint16_t triggerWait, eUltraSonicUnlock_t unlock) {
  10.         if (this->echoCount != echoCount) this->end();
  11.        
  12.         this->triggerPin = triggerPin;
  13.         pinMode(triggerPin, OUTPUT);
  14.         this->timeout = timeout;
  15.         this->triggerTime = triggerTime;
  16.         this->triggerWait = triggerWait;
  17.         this->echoCount = echoCount;
  18.        
  19.         if (this->lastMicroseconds == NULL) this->lastMicroseconds = new long[echoCount];
  20.         if (this->lastDistances == NULL) this->lastDistances = new double[echoCount];
  21.        
  22.         if (this->triggerTimes == NULL) this->triggerTimes = new unsigned long[echoCount];
  23.         if (this->echoTimes == NULL) this->echoTimes = new unsigned long[echoCount];
  24.         if (this->echoStages == NULL) this->echoStages = new int16_t[echoCount];
  25.         if (this->echoInts == NULL) this->echoInts = new int16_t[echoCount];
  26.         if (this->echoPorts == NULL) this->echoPorts = new int16_t[echoCount];
  27.         for (uint8_t i = 0; i < this->echoCount; i++) {
  28.                 this->triggerTimes[i] = 0;
  29.                 this->echoTimes[i] = 0;
  30.                 int16_t interrupt = digitalPinToInterrupt(echoPins[i]);
  31.                 if (interrupt == NOT_AN_INTERRUPT) {
  32.                         this->echoStages[i] = -1;
  33.                         this->echoInts[i] = -1;
  34.                         this->echoPorts[i] = echoPins[i];
  35.                 } else {
  36.                         this->echoStages[i] = 0;
  37.                         this->echoInts[i] = interrupt;
  38.                         this->echoPorts[i] = -1;
  39.                 }
  40.                 pinMode(echoPins[i], INPUT);
  41.         }
  42.        
  43.         // Unlock sensors that are possibly in a locked state, if this feature is enabled.
  44.         this->unlockSensors(unlock, echoPins);
  45. }
  46. void HCSR04Sensor::end() {
  47.         if (this->lastMicroseconds != NULL) delete []this->lastMicroseconds;
  48.         if (this->lastDistances != NULL) delete []this->lastDistances;
  49.         if (this->triggerTimes != NULL) delete []this->triggerTimes;
  50.         if (this->echoTimes != NULL) delete []this->echoTimes;
  51.        
  52.         if (this->echoPorts != NULL) delete []this->echoPorts;
  53.         if (this->echoInts != NULL) delete []this->echoInts;
  54.         if (this->echoStages != NULL) delete []this->echoStages;
  55.        
  56.         this->lastMicroseconds = NULL;
  57.         this->lastDistances = NULL;
  58.         this->triggerTimes = NULL;
  59.         this->echoTimes = NULL;
  60.         this->echoPorts = NULL;
  61.         this->echoInts = NULL;
  62.         this->echoStages = NULL;
  63. }
  64. void HCSR04Sensor::measureMicroseconds(long* results) {
  65.         if (results == NULL) results = this->lastMicroseconds;
  66.         bool finished = true;
  67.         bool waiting = true;
  68.         unsigned long startMicros = micros();
  69.         unsigned long currentMicros = 0;
  70.         unsigned long elapsedMicros = 0;
  71.         // Make sure that trigger pin is LOW.
  72.         digitalWrite(triggerPin, LOW);
  73.         delayMicroseconds(4);
  74.        
  75.         // Hold trigger HIGH for 10 microseconds (default), which signals the sensor to measure distance.
  76.         digitalWrite(triggerPin, HIGH);
  77.         delayMicroseconds(this->triggerTime);
  78.         // Set trigger LOW again and wait to give the sensor time for sending the signal without interference
  79.         digitalWrite(triggerPin, LOW);
  80.         delayMicroseconds(this->triggerWait);
  81.        
  82.         // Attach interrupts to echo pins for the starting point
  83.         for (uint8_t i = 0; i < this->echoCount; i++) {
  84.                 if (this->echoInts[i] >= 0 && this->echoStages[i] == 0) {
  85.                         this->echoStages[i] = 1;
  86.                         switch (i) {
  87.                                 case 0: attachInterrupt(this->echoInts[i], &triggerInterrupt0, RISING); break;
  88.                                 case 1: attachInterrupt(this->echoInts[i], &triggerInterrupt1, RISING); break;
  89.                                 case 2: attachInterrupt(this->echoInts[i], &triggerInterrupt2, RISING); break;
  90.                                 case 3: attachInterrupt(this->echoInts[i], &triggerInterrupt3, RISING); break;
  91.                                 case 4: attachInterrupt(this->echoInts[i], &triggerInterrupt4, RISING); break;
  92.                                 case 5: attachInterrupt(this->echoInts[i], &triggerInterrupt5, RISING); break;
  93.                                 case 6: attachInterrupt(this->echoInts[i], &triggerInterrupt6, RISING); break;
  94.                                 case 7: attachInterrupt(this->echoInts[i], &triggerInterrupt7, RISING); break;
  95.                                 case 8: attachInterrupt(this->echoInts[i], &triggerInterrupt8, RISING); break;
  96.                                 case 9: attachInterrupt(this->echoInts[i], &triggerInterrupt9, RISING); break;
  97.                         }
  98.                 }
  99.         }
  100.        
  101.         // Wait until all echos are returned or timed out.
  102.         while(true) {
  103.                 delayMicroseconds(1);
  104.                
  105.                 finished = true;
  106.                 waiting = true;
  107.                 currentMicros = micros();
  108.                 elapsedMicros = currentMicros - startMicros;
  109.                 for (uint8_t i = 0; i < this->echoCount; i++) {
  110.                         waiting &= elapsedMicros < this->timeout || (this->triggerTimes[i] > 0 && this->echoTimes[i] == 0 && (currentMicros - this->triggerTimes[i]) < this->timeout);
  111.                         if (this->echoPorts[i] >= 0 && this->triggerTimes[i] == 0) {
  112.                                 if (digitalRead(this->echoPorts[i]) == HIGH) this->triggerTimes[i] = micros();
  113.                         }
  114.                         if (this->triggerTimes[i] > 0 || !waiting) {
  115.                                 if (this->echoInts[i] >= 0 && (this->echoStages[i] == 1 || !waiting)) {
  116.                                         if (this->echoStages[i] == 1) this->echoStages[i] = 2;
  117.                                         detachInterrupt(this->echoInts[i]);
  118.                                 }
  119.                         } else finished &= false;
  120.                         if (this->echoInts[i] >= 0 && this->triggerTimes[i] > 0 && this->echoStages[i] == 2 && waiting) {
  121.                                 this->echoStages[i] = 3;
  122.                                 switch (i) {
  123.                                         case 0: attachInterrupt(this->echoInts[i], &echoInterrupt0, FALLING); break;
  124.                                         case 1: attachInterrupt(this->echoInts[i], &echoInterrupt1, FALLING); break;
  125.                                         case 2: attachInterrupt(this->echoInts[i], &echoInterrupt2, FALLING); break;
  126.                                         case 3: attachInterrupt(this->echoInts[i], &echoInterrupt3, FALLING); break;
  127.                                         case 4: attachInterrupt(this->echoInts[i], &echoInterrupt4, FALLING); break;
  128.                                         case 5: attachInterrupt(this->echoInts[i], &echoInterrupt5, FALLING); break;
  129.                                         case 6: attachInterrupt(this->echoInts[i], &echoInterrupt6, FALLING); break;
  130.                                         case 7: attachInterrupt(this->echoInts[i], &echoInterrupt7, FALLING); break;
  131.                                         case 8: attachInterrupt(this->echoInts[i], &echoInterrupt8, FALLING); break;
  132.                                         case 9: attachInterrupt(this->echoInts[i], &echoInterrupt9, FALLING); break;
  133.                                 }
  134.                         }
  135.                         if (this->echoPorts[i] >= 0 && this->triggerTimes[i] > 0 && this->echoTimes[i] == 0) {
  136.                                 if (digitalRead(this->echoPorts[i]) == LOW) this->echoTimes[i] = micros();
  137.                         }
  138.                        
  139.                         if ((this->triggerTimes[i] > 0 && this->echoTimes[i] > 0) || !waiting) {
  140.                                 if (this->echoInts[i] >= 0 && (this->echoStages[i] == 3 || !waiting)) {
  141.                                         if (this->echoStages[i] == 3) this->echoStages[i] = 4;
  142.                                         detachInterrupt(this->echoInts[i]);
  143.                                 }
  144.                         } else finished &= false;
  145.                 }
  146.                
  147.                 if (!waiting || finished) break;
  148.         }
  149.        
  150.         // Determine the durations of each sensor.
  151.         for (uint8_t i = 0; i < this->echoCount; i++) {
  152.                 if (this->echoInts[i] >= 0) this->echoStages[i] = 0;
  153.                 if (this->triggerTimes[i] > 0 && this->echoTimes[i] > 0) {
  154.                         long resultTime = this->echoTimes[i] - this->triggerTimes[i];
  155.                         results[i] = resultTime > 0 ? resultTime : HCSR04_INVALID_RESULT;
  156.                 } else if (this->triggerTimes[i] > 0) {
  157.                         results[i] = HCSR04_NO_ECHO;
  158.                 } else {
  159.                         results[i] = HCSR04_NO_TRIGGER;
  160.                 }
  161.                 this->triggerTimes[i] = 0;
  162.                 this->echoTimes[i] = 0;
  163.         }
  164. }
  165. void HCSR04Sensor::measureDistanceMm(float temperature, double* results) {
  166.         if (results == NULL) results = this->lastDistances;
  167.         double speedOfSoundInMmPerMs = (331.3 + 0.606 * temperature) / 1000; // Cair ≈ (331.3 + 0.606 ⋅ ϑ) m/s
  168.         long* times = measureMicroseconds();
  169.        
  170.         // Calculate the distance in mm for each result.
  171.         for (uint8_t i = 0; i < this->echoCount; i++) {
  172.                 double distanceMm = times[i] / 2.0 * speedOfSoundInMmPerMs;
  173.                 if (distanceMm < 10 || distanceMm > 4000) {
  174.                         results[i] = HCSR04_INVALID_RESULT;
  175.                 } else {
  176.                         results[i] = distanceMm;
  177.                 }
  178.         }
  179. }
  180. void HCSR04Sensor::measureDistanceCm(float temperature, double* results) {
  181.         if (results == NULL) results = this->lastDistances;
  182.         double speedOfSoundInCmPerMs = (331.3 + 0.606 * temperature) / 1000 / 10; // Cair ≈ (331.3 + 0.606 ⋅ ϑ) m/s
  183.         long* times = measureMicroseconds();
  184.        
  185.         // Calculate the distance in cm for each result.
  186.         for (uint8_t i = 0; i < this->echoCount; i++) {
  187.                 double distanceCm = times[i] / 2.0 * speedOfSoundInCmPerMs;
  188.                 if (distanceCm < 1 || distanceCm > 400) {
  189.                         results[i] = HCSR04_INVALID_RESULT;
  190.                 } else {
  191.                         results[i] = distanceCm;
  192.                 }
  193.         }
  194. }
  195. void HCSR04Sensor::measureDistanceIn(float temperature, double* results) {
  196.         if (results == NULL) results = this->lastDistances;
  197.         double speedOfSoundInCmPerMs = (331.3 + 0.606 * temperature) * 39.37007874 / 1000 / 1000; // Cair ≈ (331.3 + 0.606 ⋅ ϑ) m/s
  198.         long* times = measureMicroseconds();
  199.         // Calculate the distance in cm for each result.
  200.         for (uint8_t i = 0; i < this->echoCount; i++) {
  201.                 double distanceIn = times[i] / 2.0 * speedOfSoundInCmPerMs;
  202.                 if (distanceIn < 1 || distanceIn > 157.4804) {
  203.                         results[i] = HCSR04_INVALID_RESULT;
  204.                 }
  205.                 else {
  206.                         results[i] = distanceIn;
  207.                 }
  208.         }
  209. }
  210. void HCSR04Sensor::unlockSensors(eUltraSonicUnlock_t unlock, uint8_t* echoPins) {
  211.         if (unlock == eUltraSonicUnlock_t::unlockSkip) return;
  212.         bool hasLocked = false;
  213.         // Check if any sensor is in a locked state and unlock it if necessary.
  214.         for (uint8_t i = 0; echoPins[i] != 0; i++) {
  215.                 if (unlock == eUltraSonicUnlock_t::unlockMaybe && digitalRead(echoPins[i]) == LOW) continue;
  216.                 pinMode(echoPins[i], OUTPUT);
  217.                 digitalWrite(echoPins[i], LOW);
  218.                 hasLocked = true;
  219.         }
  220.        
  221.         if (hasLocked) delay(100);
  222.         // Revert the pinMode after potential unlocking.
  223.         for (uint8_t i = 0; echoPins[i] != 0; i++) {
  224.                 pinMode(echoPins[i], INPUT);
  225.         }
  226.        
  227.         if (hasLocked) delay(100);
  228. }
  229. void HCSR04Sensor::triggerInterrupt(uint8_t index) {
  230.         if (this->triggerTimes[index] == 0) this->triggerTimes[index] = micros();
  231. }
  232. void HCSR04Sensor::echoInterrupt(uint8_t index) {
  233.         if (this->triggerTimes[index] > 0 && this->echoTimes[index] == 0) this->echoTimes[index] = micros();
  234. }
  235. void HCSR04Sensor::triggerInterrupt0() { HCSR04.triggerInterrupt(0); }
  236. void HCSR04Sensor::triggerInterrupt1() { HCSR04.triggerInterrupt(1); }
  237. void HCSR04Sensor::triggerInterrupt2() { HCSR04.triggerInterrupt(2); }
  238. void HCSR04Sensor::triggerInterrupt3() { HCSR04.triggerInterrupt(3); }
  239. void HCSR04Sensor::triggerInterrupt4() { HCSR04.triggerInterrupt(4); }
  240. void HCSR04Sensor::triggerInterrupt5() { HCSR04.triggerInterrupt(5); }
  241. void HCSR04Sensor::triggerInterrupt6() { HCSR04.triggerInterrupt(6); }
  242. void HCSR04Sensor::triggerInterrupt7() { HCSR04.triggerInterrupt(7); }
  243. void HCSR04Sensor::triggerInterrupt8() { HCSR04.triggerInterrupt(8); }
  244. void HCSR04Sensor::triggerInterrupt9() { HCSR04.triggerInterrupt(9); }
  245. void HCSR04Sensor::echoInterrupt0() { HCSR04.echoInterrupt(0); }
  246. void HCSR04Sensor::echoInterrupt1() { HCSR04.echoInterrupt(1); }
  247. void HCSR04Sensor::echoInterrupt2() { HCSR04.echoInterrupt(2); }
  248. void HCSR04Sensor::echoInterrupt3() { HCSR04.echoInterrupt(3); }
  249. void HCSR04Sensor::echoInterrupt4() { HCSR04.echoInterrupt(4); }
  250. void HCSR04Sensor::echoInterrupt5() { HCSR04.echoInterrupt(5); }
  251. void HCSR04Sensor::echoInterrupt6() { HCSR04.echoInterrupt(6); }
  252. void HCSR04Sensor::echoInterrupt7() { HCSR04.echoInterrupt(7); }
  253. void HCSR04Sensor::echoInterrupt8() { HCSR04.echoInterrupt(8); }
  254. void HCSR04Sensor::echoInterrupt9() { HCSR04.echoInterrupt(9); }
  255. HCSR04Sensor HCSR04;
复制代码
三、库文件应用举例

下文以超声波传感器的库HCSR04来举行举例(仅分析代码用法,不作实物接线)
在导入HCSR04库之后,可打开库文件中的实例:
  1. #include <HCSR04.h>
  2. HCSR04 hc(5, 6); //initialisation class HCSR04 (trig pin , echo pin)
  3.                  //初始化超声波传感器,即表明接口号。
  4. void setup()
  5. {
  6.     Serial.begin(9600);  //串口初始化
  7. }
  8. void loop()
  9. {
  10.     Serial.println(hc.dist()); // return curent distance in serial
  11.                                // hc.dist()会返回超声波传感器检测的距离数据
  12.     delay(60);                 // 延时60毫秒
  13. }
复制代码
具体实例可参考文章——Arduino项目式编程讲授第四章——超声波测距
如果想要了解此库文件下的方法,则可以在Arduino软件中,按住【Alt / cmd】键,然后使用鼠标点击对应的库文件名,即可打开其头文件


在头文件中,可以阅读文件贡献者做出的注释来了解此库文件中可供使用的方法。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4