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?

1
  • 1
    Perhaps you should show us your code...?
    – Majenko
    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!

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.
    – gmag11
    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. 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.
    – gmag11
    Dec 22, 2015 at 12:24
  • Please see the update code example above. Cheers! 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.
    – gmag11
    Dec 22, 2015 at 23:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.