Передача функции в качестве параметра

itehno
Offline
Зарегистрирован: 18.04.2015

Добрый день. Подскажите, как передать функцию ppp() в качестве еще одного параметра (помимо stoping) в функцию Millis()

Код примерно такой. Мне это нужно для того, что бы я мог кроме ppp() подставлять какую либо иную функцию.

void loop(){
ooo();
}

int Millis(int16_t stoping) {
  static uint32_t Time = 0;
  int result;
  static int16_t Delay = stoping;
  if ((millis() - Time) > Delay) {
    ppp();
    Time = millis();
    return result;
  }
}

void ppp(){
  digitalWrite(ledFP[1],!digitalRead(ledFP[1]));
}

void ooo(){
  Millis(1000);
}

 

b707
Offline
Зарегистрирован: 26.05.2017

google function pointer as parameter

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Та блин я давно уже тему наваял , а вы б**я только проснулись #4 С 18.04.2015 видно спите.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Опишите в списке аргументов указатель на функцию и просто передавайте её имя.

itehno
Offline
Зарегистрирован: 18.04.2015

ЕвгенийП пишет:

Опишите в списке аргументов указатель на функцию и просто передавайте её имя.

Спасибо, я так и предполагал. Сейчас изучаю этот вопрос.

 

itehno
Offline
Зарегистрирован: 18.04.2015

qwone пишет:

Та блин я давно уже тему наваял , а вы б**я только проснулись #4 С 18.04.2015 видно спите.

Да. Но только теперь начал плотно изучать. Можете, пожалуйста, ткнуть носом?

itehno
Offline
Зарегистрирован: 18.04.2015

qwone пишет:

Нашел такой Ваш пример:

void func() { // это просто функция
  Serial.println("qwqewqewq");
}
void (*pFun)() = &func;// это указатель на функцию
void (*&pA)() = pFun;// это ссылка на указатель функции

void setup() {
  Serial.begin(9600);
  pA();
}
void loop() {
}

Не могли бы Вы объяснить, для чего нужен указатель и ссылка на указатель? Упростить не получится? Не совсем понятно, зачем такие сложности? И как передать функцию в качестве параметра в один из аргументов другой функции?

Извините, если написал вопрос на грани бреда, но я еще учусь. )))

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

using pvfCallback = void (*)(void);  // это тип. указатель на функцию без параметров возвр-ую  void
                                                        // pvf - необязательная мнемоника типа. pointer to void func  

void MyFunc(pvfCallback  MyCallback){  // функция, принимающая параметром указатель на другую функцию
  if (MyCallback != NULL) MyCallback();
}

void Callback(void) {
  // функция, которая будет вызвана из MyFunc
}

void loop(void){

MyFunc(Callback);  // вызываем MyFunc, передавая указатель на Callback. 

}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

тебе не на форумах надо знания получать, а прочесть для начала Библию Си от Кернигана.  Таких вопросов бы не было ( ну, если ты не вхлам тупой, канеш ). 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

itehno пишет:
для чего нужен указатель и ссылка на указатель? Упростить не получится? Не совсем понятно, зачем такие сложности?
И не будет понятно пока будете смотреть чужие примеры, вместо того, чтобы читать книги и получать систематические знания.

itehno пишет:
как передать функцию в качестве параметра в один из аргументов другой функции?
Никак. Можно передать указатель на функцию, а саму функцию - никак потому, что функция в С++ не является объектом первого класса (если Вам от такого объяснения станет легче).

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

Доброго времени суток. Дабы не множить темы подскажите как передать Serial в качестве аргумента?
Клас работает с сериал. Для универсальности хочу чтоб он работал как с хардварным так и софтварным serial.

Class myClass(){
myClass(*Serial &userSerial){
userSerial.print("Hallo world");

}
};

void setup(){
Serial.begeen(9600);
myClass(Serial);
softwareSerial mySerial(1,2);
mySerial.begeen(9600);
myClass(mySerial);
}
Написал по памяти, для пояснения сути. Дело в том, что Serial и mySerial являються разными типами данных. И в случае если тип явно не указывать tamplate tampname... то userSerial в классе не будет иметь методов (получаю такую ошибку).

itehno
Offline
Зарегистрирован: 18.04.2015

cpp
class myClass {
public:
  myClass(Stream& userSerial) {
    userSerial.print("Hello world");
  }
};

void setup() {
  Serial.begin(9600);
  myClass obj1(Serial);
  
  SoftwareSerial mySerial(1, 2);
  mySerial.begin(9600);
  myClass obj2(mySerial);
}

void loop() {
  // Ваш код для функции loop()
}
В приведенном коде уже есть пример передачи Serial в качестве аргумента. Объекты obj1 и obj2 создаются с передачей соответствующих объектов Serial и mySerial в качестве аргументов конструктора класса myClass. 
 
Таким образом, чтобы передать Serial в качестве аргумента, нужно создать объект класса, который принимает в конструкторе объект типа Stream (к которому относится и Serial), и передать в качестве аргумента при создании объекта переменную, содержащую ссылку на этот объект типа Stream. 
 
Например:
 
class MyClass {
public:
  MyClass(Stream& userSerial) {
    // используем userSerial для работы с последовательным портом
  }
};

void setup() {
  Serial.begin(9600);
  MyClass obj1(Serial); // передаем объект Serial в качестве аргумента

  // ...
}

 

 

p-a-h-a
Offline
Зарегистрирован: 17.01.2019

Благодарю. Действительно все наследуется от Stream.

Поигрался немного и все вышло.

#include <Arduino.h>
#include "SoftwareSerial.h"
#include <Stream.h>

class UniversalSerial : public Stream
{
  Stream &userSerial;

public:
  UniversalSerial(Stream &userSerial) : userSerial(userSerial) {}
  virtual size_t write(uint8_t data) override { return userSerial.write(data); }
  virtual int available() override { return userSerial.available(); }
  virtual int read() override { return userSerial.read(); }
  virtual int peek() override { return userSerial.peek(); }
  virtual void flush() override { userSerial.flush(); }
  using Print::write;
};

void setup()
{
  {
    Serial.begin(74880);
    UniversalSerial hardware(Serial);
    hardware.print("\nHardware");
    hardware.write(": Ok");
    hardware.println();
    hardware.flush();
    Serial.end();
  }
  {
    SoftwareSerial sSerial(3, 1);
    sSerial.begin(74880);
    UniversalSerial software(sSerial);
    software.flush();
    software.println("Software");
    software.flush();
    sSerial.end();
  }
}

void loop() { yield(); }