FUNCREF to a static function not working?

Hi!

In my code I would like to use a function reference. According to the help file the prototype function cannot be static, but the referenced function can be (i.e. one can store a static function into a FUNCREF). But it seems this is not working on Igor 6.37, or am I misunderstanding something from the help file?

Basically I have a function from which I want to call various static functions using a FUNCREF. I wrote a (non-static) prototype function, but then when I create a FUNCREF like FUNCREF protofunc f = $sFunc, where sFunc is a string with the name of the (static) function I would like to call, the FuncRefInfo(f) function returns a "failed" func reference (i.e. f is pointing to the prototype function). All the functions are part of the same procedure file.

If I remove the static keyword from the function declaration (of the function I want to call via a function reference) the function reference works as expected ...

Thanks for any help or suggestions.

Gregor
It would be best if you can provide a minimal example that can be used to demonstrate the problem.
Just off the top of my head ... By chance, does your procedure have a Module or Independent Module designation to it? I don't know whether FuncRef is limited so that, in such cases, the STATIC functions require their Module (and/or Independent Module) prefix as well.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
OK, here is a short example code I quickly wrote to show the issue (maybe it is just me not understanding properly the FUNCREF ...).
Just check the output of the FuncRefInfo lines.

#pragma rtGlobals=3     // Use modern global access method and strict wave access.

Structure PeakStruct
    WAVE pw
    WAVE yw
    WAVE xw
EndStructure

Function PeakProtoFunc(s)
    STRUCT PeakStruct &s
   
    s.yw = NaN
End

static Function GaussPeakStaticFunc(s)
    STRUCT PeakStruct &s
   
    s.yw = s.pw[0]*Gauss(s.xw, s.pw[1], s.pw[2])
End

Function GaussPeakNonStaticFunc(s)
    STRUCT PeakStruct &s
   
    s.yw = s.pw[0]*Gauss(s.xw, s.pw[1], s.pw[2])
End

Function Test()
   
    STRUCT PeakStruct ss
    Make /FREE/O/N=(100) xw, yw
    Make /FREE/O/N=(3) pw={1, 0, 0.5}
    xw = -2 + 4*p/(numpnts(xw)-1)
   
    WAVE ss.xw = xw
    WAVE ss.pw = pw
    WAVE ss.yw = yw
   
    // FUNCREF to static function NOT working
    String sFunc = "GaussPeakStaticFunc"
    FUNCREF PeakProtoFunc ff = $sFunc
    print FuncRefInfo(ff)
   
    // FUNCREF to non-static function IS working
    sFunc = "GaussPeakNonStaticFunc"
    FUNCREF PeakProtoFunc ff = $sFunc
    print FuncRefInfo(ff)

    return 0
End



--
Gregor K
ALOISA Beamline
Elettra Synchrotron
The documentation says:

FUNCREF variables can refer to external functions as well as user-defined functions. However, the prototype function must be a user-defined function and it must not be static.
Although you can store a reference to a static function in a FUNCREF variable, you can not then use that variable with Igor operations that take a function as an input. FuncFit is an example of such an operation.

A.G.
WaveMetrics, Inc.
Igor wrote:
The documentation says:

FUNCREF variables can refer to external functions as well as user-defined functions. However, the prototype function must be a user-defined function and it must not be static.


Yes, the prototype function in my case is not static.

Igor wrote:

Although you can store a reference to a static function in a FUNCREF variable, you can not then use that variable with Igor operations that take a function as an input. FuncFit is an example of such an operation.


Here is the issue, I cannot store a reference to a static function at all.
Furthermore, I am not using that reference as an input to an Igor operation.
Therefore according to the help file which I have read the above code example should work.

Can You please clarify what I am misunderstanding (doing wrong) here?

Thanks!

--
Gregor K
ALOISA Beamline
Elettra Synchrotron
Function protoFunc(aa)
    variable aa
 
End
 
static Function func1(aa)
    variable aa

    print "func1"
End
 
Function func2(aa)
    variable aa

    print "func2"
End
 
 
Function Test()
 
    // FUNCREF to static function now working
    String sFunc1 = "#func1"
    FUNCREF protoFunc f1 = $sFunc1
    f1(1)
 
    // FUNCREF to non-static function IS working
    String sFunc2 = "func2"
    FUNCREF protoFunc f2 = $sFunc2
    f2(1)
 
    return 0
End
I think it is useful to point out that when using FuncRefs and static functions, you should use moduleName#functionName syntax.

The #functionName syntax isn't intended, but this is:

#pragma moduleName=myMod // important for referring to static functions.

Function protoFunc(aa)
    variable aa

        print "if you got here, the FuncRef failed"
End
 
static Function func1(aa)
    variable aa
 
    print "func1"
End
 
Function func2(aa)
    variable aa
 
    print "func2"
End
 
 
Function Test()
 
    // FUNCREF to static function now working
    String sFunc1 = "myMod#func1"  // Note the moduleName and # separator
    FUNCREF protoFunc f1 = $sFunc1
    f1(1)
 
    // FUNCREF to non-static function IS working
    String sFunc2 = "func2"
    FUNCREF protoFunc f2 = $sFunc2
    f2(1)
 
    return 0
End

--Jim Prouty
Software Engineer, WaveMetrics, Inc.
JimProuty wrote:
I think it is useful to point out that when using FuncRefs and static functions, you should use moduleName#functionName syntax.

The #functionName syntax isn't intended, but this is:

#pragma moduleName=myMod // important for referring to static functions.




Ah ha!

When I am back at my desktop, I'll have to dig up the post from long ago about using Modules and Independent Modules and Statics.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH
JimProuty wrote:
I think it is useful to point out that when using FuncRefs and static functions, you should use moduleName#functionName syntax.


Jim (and others) thank you very much for clarifying. It seems I forgot that the static keyword is bound to the use of Modules.
As always I appreciate your help very much!

Gregor
--
Gregor K
ALOISA Beamline
Elettra Synchrotron
gregorK wrote:
It seems I forgot that the static keyword is bound to the use of Modules.


The moduleName pragma is needed only if you refer to a static function either from outside of the procedure file you're using or if you refer to the static function with a FUNCRef.

You can call a static function from within the same procedure file without having a #pragma moduleName=something. Not always needing the pragma is the source of people's confusion.

--Jim Prouty
Software Engineer, WaveMetrics, Inc.
jjweimer wrote:

Ah ha!

When I am back at my desktop, I'll have to dig up the post from long ago about using Modules and Independent Modules and Statics.


Found it: "Synopsis: Programming With Modules and IndependentModules"

August 6, 2010

http://www.igorexchange.com/node/1688

--Jim Prouty
Software Engineer, WaveMetrics, Inc.
JimProuty wrote:
jjweimer wrote:

Ah ha!

When I am back at my desktop, I'll have to dig up the post from long ago about using Modules and Independent Modules and Statics.


Found it: "Synopsis: Programming With Modules and IndependentModules"

August 6, 2010

http://www.igorexchange.com/node/1688

--Jim Prouty
Software Engineer, WaveMetrics, Inc.


Thanks!

I've added a link there back to this thread as an update.

--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAH