我可以动态地强制转换函数自变量吗?

问题描述

我想使用c实现行进立方体算法。该算法从体积创建曲面。有时,该函数将接收描述体积的粒子数组,有时,将接收标量字段函数(接收某些位置并返回某些值的函数)。而不是制作两个单独的函数,我希望行进立方体函数接收一个空指针。如果所需的方法是粒子的表面,则将指针强制转换为粒子数组,否则将其强制转换为函数指针。这是我想要的说明:

particle_array* global_par_array;
double (*global_scalar_field)(location);

double value_according_to_par_array(location loc){
        //use the global_par_array and return a value
        return value;
}
double value_according_to_scalar_field(location loc){
        //use the global_scalar_field and return a value
        return value;
}
void marching_cubes(mesh* surface,void* par_array_or_function,char is_par_array){
//                  ^ need this argument to 
//                    be dynamically casted
    double (*method)(location loc);
    if (is_par_array){
        global_par_array = (particle_array*)(*par_array_or_function);
        method = value_according_to_par_array;
    }
    else{
        global_scalar_field = (double(*)(location))(*par_array_or_function);
        method = value_according_to_scalar_field;
    }
    //do the marching cubes algorithm according to method,changing *surface
    return;

我会将此函数形式称为python(使用ctypes),以便跟踪自己,我的意思是,如果我传递了一个强制转换为的函数,我将在0参数中传递is_par_array void指针,或传递1如果我传递了强制转换为void指针的粒子数组,这在c中是允许的吗?

解决方法

否,您不能可靠地使用void*来保存函数指针。 void*是通用的 object 指针类型。

更重要的是,从程序设计的角度来看,将相同的指针/参数用于完全无关的目的是没有意义的。解决此问题的正确方法是退后一步,重新思考程序设计。

一些设计思路:
您可以 使用void*指向任何结构,而该结构又包含任何类型,因此这是一个显而易见的解决方案。同样,由于您使用相同的函数格式,因此可以将函数作为确定函数的参数传递。即,传递要用作“回调”的函数指针。通常,使用全局变量是不好的,因此,如果我们可以进行设计,那就更好了。

我完全不知道实际程序会做什么,但是这里建议使用C语言中的传统泛型编程进行重新设计:

typedef double march_cube_t (location,void*);


double march_particle_array (location loc,void* data)
{
  // cast data to a struct or object pointer type specific for this function
  ...
  return value;
}

double march_scalar_field (location loc,void* data)
{
  // cast data to a struct or object pointer type specific for this function
  ...
  return value;
}

void marching_cubes(mesh* surface,march_cube_t* algo,void* data)
{
  ...
  double result = algo(some_location,data);
}

还要考虑常量正确性(如果适用)。如果您不需要修改数据,则应为const void*

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...