Using THttpServer::RegisterCommand with class member functions

Dear ROOT community!

I’d like to ask if it’s possible to register a class member function into THttpServer’s RegisterCommand method with a cmake compiled project. In general things work fine when I use simpler structures with free functions that get registered.
I’m trying to get a structure like below to work, where other classes holding such a HttpServerBase object can register some of their member functions to be executed.

Simplified:

class HttpServerBase {
public:
  HttpServerBase(int port, std::function<void()> f) : m_mthdNoArgs(f) {
  m_http_server =
      std::make_unique<THttpServer>(("http:" + std::to_string(port)).c_str());

  m_http_server->SetDefaultPage(
      "/path/to/my/webpage.html");

  m_http_server->RegisterCommand(
      "/CmdFolder/noArgFunc", "callMethodWithougArgs()");
  //m_http_server->RegisterCommand(
     // "/CmdFolder/noArgFunc", "HttpServerBase::callMethodWithougArgs()"); doesn't work either

 }

  void callMethodWithougArgs() { m_mthdNoArgs(); }


private:
  std::unique_ptr<THttpServer> m_http_server = nullptr;

  std::function<void()> m_mthdNoArgs;

  ClassDef(HttpServerBase, 1)
};

And currently try to generate the dict with the following linkdef

#ifdef __CINT__

#pragma link C++ class HttpServerBase;
#pragma link C++ function HttpServerBase::callMethodWithougArgs();

#endif

What I get when executing the command in the webbrowser, is either

input_line_11:2:3: error: use of undeclared identifier 'callMethodWithougArgs'
 (callMethodWithougArgs())
  ^
Error in <HandleInterpreterException>: Error evaluating expression (callMethodWithougArgs()).
Execution of your code was aborted.

or

input_line_10:2:24: error: call to non-static member function without an object argument
 HttpServerBase::callMethodWithougArgs()
 ~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
^C

In the html I have

    <button id="btn_connect" type="button">Connect</button>

    <script type="text/javascript">
      document.getElementById("btn_connect").onclick = function () {
        JSROOT.NewHttpRequest("CmdFolder/noArgFunc/cmd.json", "object").send();
      };
    </script>

Is there maybe something wrong with the way I define the LinkDef? Or do I have no choice but make the member functions static?
Thanks a lot!

Hi @aleopold,

If the function is not to be called on a specific object instance, you should declare it as static, as in

static void callMethodWithougArgs() { m_mthdNoArgs(); }

Given that static member function has the same signature as a non-member function, that would make it work if you also use the form

m_http_server->RegisterCommand("/CmdFolder/noArgFunc", "HttpServerBase::callMethodWithougArgs()");

Other than that, if you need the call to be issued on a particular object, you can take a look at the examples in THttpServer::RegisterCommand().

Cheers,
J.

Hi @jalopezg!

Thanks a lot for your reply!

Of course! I can just make HttpServerBase inherit from TNamed (which I don’t mind), give it some name (e.g. “WebServer”) and register the class itself

m_http_server->Register("/", this);

m_http_server->RegisterCommand("/CmdFolder/noArgFunc",
                                 "/WebServer/->callMethodWithougArgs()");

Then I don’t need to mess with statics at all.
I think this should solve my (current) problem. On to the next one :slight_smile: Thanks again!!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.