How to call a class method by a pointer
Posted: Tue Mar 19, 2024 10:27 pm
I have a question about how to call a class method with a pointer. Below the code of an RTC.
The important parts of the code are these.
The errors I have are related to the line "TMSSelect->pt2function(dummyptr);" I have the following errors:
expression preceding parentheses of apparent call must have (pointer-to-) function typeC/C++(109)
RTC_Clock::tmSource_t *RTC_Clock::TMSSelect
'pt2function' was not declared in this scope
void (RTC_Clock::*RTC_Clock::tmSource_t::pt2function)(void *)
Can someone tell me the correct syntax how I have to call the line "TMSSelect->pt2function(dummyptr);" that points to a xxx_sync method using a pointer.
Thanks Oscar Goos
The important parts of the code are these.
Code: Select all
// declaration of a time souce struct with a pointer to method.
typedef struct tmSource_t {
char id[10];
CLKstate state;
CLK_Quality quality;
void (RTC_Clock::*pt2function)(void*);
} tmSource_t;
Code: Select all
//The configuration of the time souce struct with a pointer to the xxx_sync methods
tmSource_t TMSource[4] = { {"NTP1", AVAILABLE, STM1, &RTC_Clock::NTP_sync }, {"NTP2", NOTAVAIL, STM4, &RTC_Clock::NTP_sync},
{"DS3231", AVAILABLE, STM4, &RTC_Clock::DS3231_sync}, {"SOFTW", NOTAVAIL, STM4, &RTC_Clock::SOFT_sync} };
tmSource_t *TMSSelect=&TMSource[0];
Code: Select all
//The call to the xxxsync method pointed by a TMSSelect pointer
case RTC_SYNC: {
tm.epoch = NTP.NTP.epoch;
NTP.new_epoch=false;
TMSSelect->pt2function(dummyptr);
} break;
expression preceding parentheses of apparent call must have (pointer-to-) function typeC/C++(109)
RTC_Clock::tmSource_t *RTC_Clock::TMSSelect
'pt2function' was not declared in this scope
void (RTC_Clock::*RTC_Clock::tmSource_t::pt2function)(void *)
Can someone tell me the correct syntax how I have to call the line "TMSSelect->pt2function(dummyptr);" that points to a xxx_sync method using a pointer.
Thanks Oscar Goos
Code: Select all
#ifndef RTC_Clock_H
#define RTC_Clock_H
#define RTC_Debug 1 // RTC debug level
#include <Wire.h>
#include <NTP_client.h>
#include <stdio_handler.h>
#include <Gas_Meter_AS5600.h>
#define STOP true
#define BCD2DEC(bcdval) (((bcdval>>4)*10) + (bcdval & 0x0F))
#define DEC2BCD(decval) (((decval/10)<<4) + (decval%10))
//extern stdio_handler stdio;
//extern NTP_Client NTP;
//extern DS3231 DS3231_RTC;
//class RTC_Clock: public NTP_Client, public DS3231 {
class RTC_Clock: public NTP_Client {
public:
enum command { RTC_INIT, RTC_SYNC, TMDT2STR, INC_SEC };
enum CLKstate { AVAILABLE, NOTAVAIL, OOS, ERRORED };
enum CLK_Quality { STM0, STM1, STM2, STM3, STM4 };
enum TSI { TIME, DATE, IP};
typedef struct RTC_t {
uint8_t id; // Struct identifier for future use
uint8_t sec; // seconds, 00..59
uint8_t min; // minuts, 00..59
uint8_t hr; // hours, 00..23
uint8_t DinW; // Day in week, 01..07
uint8_t DinM; // Day in month, 01..31
uint16_t DinY; // Day in year 01..366
uint8_t MinY; // Month in year, 01..12
uint16_t year; // Year 2000..2100
uint32_t SinD; // seconds in day, 00..86399
uint8_t isdst; // flag telling you dalight saving time.
uint32_t epoch; // epoch time in sec since 1/1/1970
int16_t error; // Time error in usec/sec
int32_t tzone; // Time zone in signed seconds, MX=-6*3600
int16_t dst; // current Daylight Saving Time offset value
char tmstr[9] ="00:00:00"; // buffer for time string
char dtstr[11]="00/00/0000"; // buffer for date string
} RTC_t;
typedef struct reg {
uint8_t sec; // seconds, 00..59
uint8_t min; // minuts, 00..59
uint8_t hr; // hours, 00..23
uint8_t DinW; // Day in week, 01..07
uint8_t DinM; // Day in month, 01..31
uint8_t MinY; // Month in year, 01..12
uint8_t YinC; // Year in century, 00..99 respresenting 2000..2099)
}__attribute__((packed, aligned(1))) reg_t;
typedef struct tmSource_t {
char id[10];
CLKstate state;
CLK_Quality quality;
void (RTC_Clock::*pt2function)(void*);
} tmSource_t;
typedef struct month_t {
const char* id;
uint8_t daycnt;
}month_t;
typedef struct week_t {
const char* id;
uint8_t index;
};
month_t month[13]= {{"",0},{"Jan",31},{"Feb",28},{"Mar",31},{"Apr",30},{"May",31},{"Jun",30},{"Jul",31},{"Aug",31},{"Sep",30},{"Oct",31},{"Nov",30},{"Dec",31} };
week_t week[8]= {{"",0},{"Mo",1},{"Tu",2},{"We",3},{"Th",4},{"Fr",5},{"Sa",6}, {"Su",7}};
RTC_Clock();
RTC_t tm;
void Driver(RTC_Clock::command) ;
void UnixTime_to_StandardTime (uint32_t);
uint32_t StandardTime_to_UnixTime(char*, char*);
void epoch2time (uint32_t);
void parce(TSI, char*, void*);
void DST_forward();
void DST_backward();
void DS3231_init();
void DS3231_sync(void*);
void NTP_sync(void*);
void SOFT_sync(void*);
NTP_Client NTP;
tmSource_t TMSource[4] = { {"NTP1", AVAILABLE, STM1, &RTC_Clock::NTP_sync }, {"NTP2", NOTAVAIL, STM4, &RTC_Clock::NTP_sync},
{"DS3231", AVAILABLE, STM4, &RTC_Clock::DS3231_sync}, {"SOFTW", NOTAVAIL, STM4, &RTC_Clock::SOFT_sync} };
tmSource_t *TMSSelect=&TMSource[0];
private:
// void str2tmdt(char*tmstr, char*dtstr);
uint8 I2C_adr=0x068;
reg_t DSreg;
void *dummyptr;
protected:
};
RTC_Clock::RTC_Clock() {
// tm.tmsptr = ptr2tmstr;
// tm.dtsptr = ptr2dtstr;
tm.epoch=1688011472; // testing purpose
//epoch2time(tm.epoch); // testing purpose
UnixTime_to_StandardTime(tm.epoch); // testing purpose
}
void RTC_Clock::Driver(RTC_Clock::command cmd) {
uint8_t n;
String TDstr;
switch (cmd) {
case RTC_INIT: {
for (n=0; n<4; n++) if ((TMSource[n].quality < TMSSelect->quality) && (TMSource[n].state==AVAILABLE )) { TMSSelect = &TMSource[n]; }
stdio.printf("Selected Clock:[%u:4], %s, Status: %u, Quality:%u\n\n",n+1, TMSSelect->id, TMSSelect->state, TMSSelect->quality ); //to be improved
tm.tzone=-6*3600; // temperaly set o mexico
tm.dst=0; // Dailight Saving Time mexio=0;
}break;
case RTC_SYNC: {
tm.epoch = NTP.NTP.epoch;
NTP.new_epoch=false;
//epoch2time(tm.epoch);
//if (TMSource[1].state==AVAILABLE) UnixTime_to_StandardTime (tm.epoch);
//if (TMSource[3].state==AVAILABLE) DS3231_sync();
TMSSelect->pt2function(dummyptr);
} break;
case TMDT2STR: {
sprintf(tm.tmstr,"%02u:%02u:%02u", tm.hr, tm.min, tm.sec);
sprintf(tm.dtstr,"%02u/%02u/%04u", tm.DinM, tm.MinY, tm.year);
//stdio.printf("Time : %s\t Date: %s\n", tm.tmstr, tm.dtstr);
} break;
case INC_SEC: {
tm.epoch++;
NTP.state_machine();
if(NTP.new_epoch) Driver(RTC_Clock::RTC_SYNC);
} break;
}
}