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