CINT and function pointers

Hello!

The following code:

#include "CallFunc.h"
#include "Class.h"
#include "stdlib.h"

double fit(double *x, double *y)
{
  return 0;
}

int main(void) {
  
  long addr, offset;
  char *title = "fcn";
  double i = 0;
  double j = 3;
  int k = 6;

  // "char*,(double*)(double*,double*),double,double,int"
  // does not seem to work even...
  char *cproto = "char*,void*,double,double,int"; 

  G__ClassInfo *klass = new G__ClassInfo ("TF1");
  G__CallFunc *func = new G__CallFunc();
  G__MethodInfo *minfo = new 			G__MethodInfo(klass->GetMethod("TF1", 
                                                            cproto, &offset));

  func->SetArg((long)title);
  func->SetArg((long)fit);
  func->SetArg((double)i);
  func->SetArg((double)j);
  func->SetArg((long)k);
  
  if (minfo->InterfaceMethod())
    func->SetFunc(*minfo);

  printf("%s\n", minfo->GetPrototype());
  addr = func->ExecInt((void*)((long)NULL + offset));

  return 1;
}

Produces the following error:

elathan@velka:/opt/root> !g++
g++ -Wall `root-config --cflags --libs` cf.C -o cf
elathan@velka:/opt/root> ./cf 
TF1 TF1::TF1(const char* name,void* fcn,Double_t xmin,Double_t xmax,Int_t npar)
Function:fcn cannot be compiled

Any hints?

Regards,
Elias

Hello Elias,

I think this is about how TF1 works. I don’t have ROOT documentation on hand, but if I remember correctly, the first argument of TF1 constructor has to have name of callback function. In your case “fit”. Correct me
if I am wrong, Rene.

BTW, right forum for this topic is “ROOT support”, I think.

Thank you
Masa Goto

Dear Masa,

[quote=“Masaharu Goto”]Hello Elias,

I think this is about how TF1 works. I don’t have ROOT documentation on hand, but if I remember correctly, the first argument of TF1 constructor has to have name of callback function. In your case “fit”. Correct me
if I am wrong, Rene.
[/quote]

I tried to provide “fit” as the first argument of the TF1 constructor and again
TF1 failed to compile the fit function.

My problem is not how TF1 works, but how to feed a funtion pointer to a C++ method via CINT’s API. TF1’s ctor is an example method.

Regards,
Elias

Hello Elias,

I see. Indeed, that was the title of your posting.
Let me explain how you can feed function pointers in Cint.
In a sense, it is as simple as giving function name. For example,

void f();
void test() {
void (*p2f)() = f;
p2f();
}

But how it works is not simple at all. There are several different
cases.

  1. Interpreted function
    1.1. bytecode compiled interpreted function
    1.2. bare interpreted function
    This case, cint returns pointer to proprietary data which
    points to the function. Implementation is different for
    bytecode and non-bytecode function. But, either case,
    only cint understands meaning of that pointer.

  2. Compiled function
    For compiled function, what cint returns depends on how
    you compiled Cint. If -DG__TRUEP2F is defined for cint
    build, true pointer to function which can be directly used
    by native code will be returned. If not, cint returns pointer
    to wrapper function.

  3. Member function.
    Cint can not handle pointer to member function.

This is quite complex. For more information, please refer to
cint/ref.txt and search G__isinterpretedp2f API. You’ll find
example code.

Thank you
Masa Goto