我正在尝试将一些用C编写的旧DSP代码转换为Java,然后转换为C#。我不明白参数“double(* Window)(double)”是什么意思以及如何在Java代码中引用它。以下功能让我不确定该怎么做。
void WinFirI(float LowOmega, float UppOmega,
float *Shape, int Len, double (*Window)(double), float shift)
{ int i; double time,phase,shape;
// printf("WinFirI: %5.3f %5.3f %d\n",LowOmega,UppOmega,Len);
for(i=0; i<Len; i++)
{ time=i+(1.0-shift)-(float)Len/2; phase=2*M_PI*time/Len;
if(time==0) shape=UppOmega-LowOmega;
else shape=(sin(UppOmega*time)-sin(LowOmega*time))/time;
// printf("%2d %5.1f %5.2f %7.4f %7.4f\n",i,time,phase,shape,(*Window) (phase));
Shape[i]=shape*(*Window)(phase)/M_PI; }
}
到目前为止,我已经写过:
public void WinFirI(float LowOmega, float UppOmega,
float[] Shape, int Len, double[] Window, float shift) {
double time;
double phase;
double shape;
// printf("WinFirI: %5.3f %5.3f %d\n",LowOmega,UppOmega,Len);
for(int i=0; i<Len; i++) {
time = i +(1.0-shift) - (float)Len/2;
phase = 2 * Math.PI * time / Len;
if(time==0) {
shape = UppOmega - LowOmega;
}
else {
shape=(Math.sin(UppOmega*time) - Math.sin(LowOmega*time)) / time;
}
// printf("%2d %5.1f %5.2f %7.4f %7.4f\n",i,time,phase,shape, (*Window)(phase));
//Shape[i]=shape*(*Window)(phase)/M_PI;
Shape[i] = shape * Window[phase]/Math.PI;
}
}
答案 0 :(得分:6)
使用参数double返回double的函数指针。
答案 1 :(得分:4)
作为补充说明,在Java中实现此函数指针行为将通过匿名类/接口完成。
double Window(double param);
在Java中将是:
interface WindowFnWrapper {
double Window(double param);
}
然后函数签名将是:
public void WinFirI(float LowOmega, float UppOmega,
float[] Shape, int Len, WindowFnWrapper WindowWrapper, float shift)
每次拨打Window()
时,都会将其替换为WindowWrapper.Window()
。
答案 2 :(得分:1)
声明double (*Window)(double)
声明参数Window
,其值是指向函数的指针。该函数必须是一个以double
为参数的函数,并返回double
。
在你的C代码中,(好吧,实际上是已注释掉的部分),该指针被取消引用,并调用该函数,传递phase
作为其参数。也就是说,表达式(*Window) (phase)
的值只是调用传入其地址的函数的结果。
如果您使用的是Java 8或更高版本,则最近的可用等效项是来自Function
包的java.util.function
泛型类。所以,如果你写
import java.util.function.Function;
然后您可以将参数声明为
Function<Double,Double> window
并将其用作
window.apply(phase);
这与C代码之间唯一真正的区别是Java泛型的类型参数不能是基本类型,例如double
。
Double
是一种类似double
的引用类型,但Double
可以为空,而double
则不能。实际上,这应该对您的代码没有任何影响,除了您可能想要添加一些错误处理来处理window.apply(phase)
求值为null的情况。