说实话,我不是一个好的程序员。我的任务是用 CUBA 库更改数值集成例程。但这并不一定重要。我得到的是一个定制的例程,其中集成了许多功能,定义如下:
float spectra(float x[],float)
被传递到数字维加斯例程
float integrate ( float (*fxn)(float[],float), unsigned long ncall, int itmx )
通过调用
integrate(spectra,ncall,itmx);
然后将其传递到实际例程。这一切都很好。
现在,在 CUBA 例程中我进行集成:
Cuhre(NDIM, NCOMP, Integrand, USERDATA, NVEC, ... ,integral, ...);
重要的是 Integrand 是函数,而 USERDATA 是一个空指针,用于将您需要的任何额外内容传递给 Integrand。有点像 GSL 例程。
我不想重写所有“spectra”函数以获得 CUBA 例程的正确形式。我只是想在两者之间有一个包装器。
被积分有类型转换:
static int Integrand(const int *ndim, const cubareal xx[], const int *ncomp, cubareal ff[], void *userdata);
其中 xx[] 是输入(目前只有 1),ff[] 是输出(也是 1)。 userdata 是我需要类型转换的 void 指针。
我的目标是制作一个包装器,以便在程序中调用的任何位置: 积分(函数,...) 我可以随心所欲地替换为 集成CUBA(函数,...)
我的尝试是将 Integrand 函数定义为一个空白模板,传递 USERDATA,该模板被类型转换为该 float 函数,然后从那里开始执行。我在下面的声明中应该写什么?
static int Integrand(const int *ndim, const cubareal xx[], const int *ncomp, cubareal ff[], void *userdata) {
#define f ff[0]
float xxx[ndim]; //xx is inputs, ff is outputs
xxx[0] = xx[0]; //ndim is 1 for now.
//here I try to cast this void pointer
float (*fxn)(float[],float) = NULL;
// What do I put here??????
*fxn = ???
f = fxn(xxx,0.0);
return f ;
}
最后我会有一个例行公事:
float integrateCUBA ( float (*fxn)(float[],float), unsigned long ncall, int itmx )
{
int comp, nregions, neval, fail;
cubareal integral[NCOMP], error[NCOMP], prob[NCOMP];
Cuhre(NDIM, NCOMP, Integrand, &fxn, NVEC, ...
我通过 USERDATA 指针发送“&fxn”。
我希望我说得清楚。实际上,我想做的是通过 void 指针传递指向函数“float (*fxn)(float[],float)”的指针,然后正确地将其类型转换回来。
这段代码是用 C/C++ 编写的(这是由除了我以外的人对一堆旧科学代码进行的可怕 SCSS 。)它将用 c++11 进行编译,所以如果有一个简单的静态强制转换方法,我可以使用那个也是。
非常感谢您的建议!
最佳答案
您应该能够进行强制转换,但语法不可读:
float (*fxn)(float[],float) = (float (*)(float[],float)) userdata;
// or static_cast<float (*)(float[],float)>(userdata);
f = fxn(xxx,0.0);
使用 typedef 可以提高可读性:
typedef float (*Function)(float[],float);
Function fxn = (Function) userdata;
关于c++ - 使用 void 指针时转换函数(CUBA Nint 例程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30050995/