0

I am trying to develop a NTP client library for ESP8266/Arduino to make adding NTP sync an easier task.

Basically, I've thought about a constructor as NTPClient(String host, int interval); and a NTPClient.begin() function to register sync function.

My problem is with that registering.

I have a public function: time_t ntpClient::getNtpTime() that connects to NTP server, decodes the response and returns a time_t variable.

Then, inside boolean ntpClient::begin() function I try to run setSyncProvider(ntpClient::getNtpTime). I've also tried to use setSyncProvider(this->getNtpTime).

I get a compile error here:

ntpClient.cpp:In member function 'boolean ntpClient::begin()
ntpClient.cpp:79:39: error: cannot convert 'ntpClient::getNtpTime' from type 'time_t (ntpClient::)() {aka long int (ntpClient::)()}' to type 'getExternalTime {aka long int (*)()}
 setSyncProvider(ntpClient*:getNtpTime)
Error compiling project sources

What could I do to allow registering this function as sync provider to hide NTP internals to my sketches?

Greenonline
3,1527 gold badges36 silver badges48 bronze badges
asked Dec 18, 2015 at 22:54
1
  • 1
    Perhaps you should show us your code...? Commented Dec 18, 2015 at 23:00

1 Answer 1

0

What could I do to allow registering this function as sync provider to hide NTP internals to my sketches?

The function should be a static member function. A "normal" member function does not have the right prototype as there is a hidden parameter ("this").

static time_t getNtpTime();

To solve this you need a single-ton (an instance of the client class) that the static function can use.

class NTPClient {
public:
 NTPClient() ...
 {
 ...
 s_client = this;
 }
 time_t getNtpTime();
 ...
 static time_t getNtpTime() ( return (s_client->getNtpTime()); }
 ...
protected:
 static NTPClient* s_client;
 ...
}; 
...
NTPClient::s_client = NULL;
...
NTPClient ntpClient;
...
setSyncProvider(NTPClient::getNtpTime)

Alternatively a global function and a known instance:

class NTPClient { ... };
extern NTPClient ntpClient;
...
time_t getNtpTime() { return (ntpClient.getNtpTime()); } 
...
setSyncProvider(getNtpTime) 

Cheers!

answered Dec 18, 2015 at 23:16
6
  • It was that, thank you. I've tried to change getNtpTime() to static but doing that makes impossible to access variables and non static funcions. So, the only possibility I see is adding a static funcion in main program that wraps a non static ntpClient.getNtpTime(). I'm not an expert C++ programmer at all. Do you think there is any other possibility? I'll upload my code to github and publish here the link. Commented Dec 20, 2015 at 17:16
  • That is what the last line was all about. You need an instance that the static member function may use. For instance, add a static ntpClient pointer to the class and assign it in the constructor. The static member function can then use that to call the implementation. Commented Dec 20, 2015 at 17:44
  • I've uploaded my code to https://github.com/gmag11/NtpClient. I'll check the link about single-ton design pattern. Commented Dec 22, 2015 at 12:24
  • Please see the update code example above. Cheers! Commented Dec 22, 2015 at 12:51
  • I got it working finally. I've done sync provider registering in setup() function. I will try to add a begin member function in a later moment. Last version is on GitHub. Thank you for your recommendation about singleton. Commented Dec 22, 2015 at 23:32

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.