函数指针和函数由于参数不兼容

function pointer and function is incompatible because of arguments

我已经阅读了Understanding and Using C Pointers这本书并尝试编译下面的代码。但是在编译之后我得到了警告:assignment from incompatible pointer type

我检查了代码,发现函数指针fptrSet和函数ShapeSetX不兼容,因为fptrSet的第一个参数是void *而函数ShapeSetX是Shape *.

我该如何解决这个问题? 谢谢!

typedef void (*fptrSet)(void*, int);
typedef int  (*fptrGet)(void*);
typedef void (*fptrDisplay)();    

typedef struct _vfunc
{
    fptrSet     setX;
    fptrGet     getX;
    fptrSet     setY;
    fptrGet     getY;
    fptrDisplay display;    
} vFunc;    

typedef struct _shape
{
    vFunc function;
    int x;
    int y;
} Shape;

void displayShape(){
    printf("Shape\n");
}
void ShapeSetX(Shape *shape, int x){
    shape->x = x;
}
void ShapeSetY(Shape *shape, int y){
    shape->y = y;
}
int ShapeGetX(Shape *shape){
    return shape->x;
}
int ShapeGetY(Shape *shape){
    return shape->y;
}    

Shape *newShape()
{
    Shape *shape = (Shape *)malloc(sizeof(Shape));
    shape->x = 10;
    shape->y = 10;
    shape->function.setX = ShapeSetX;
    shape->function.getX = ShapeGetX;
    shape->function.setY = ShapeSetY;
    shape->function.getY = ShapeGetY;
    shape->function.display = displayShape;
    return shape;
}

您必须遵守指针定义:指针需要第一个参数是指向 void 的指针,因此您的函数实现应该将第一个参数设为 void:

void ShapeSetX(void *void_shape, int x){
    Shape *shape = (Shape*) void_shape;
    shape->x = x;
}
void ShapeSetY(void *void_shape, int y){
    Shape *shape = (Shape*) void_shape;
    shape->y = y;
}
int ShapeGetX(void *void_shape){
    Shape *shape = (Shape*) void_shape;
    return shape->x;
}
int ShapeGetY(void *void_shape){
    Shape *shape = (Shape*) void_shape;
    return shape->y;
} 

我本来想说 "Why don't you replace void with Shape then?",直到我意识到 Shape 还没有被定义——你也不能交换这两个定义,因为 Shape 需要 [=16] =] 需要 typedefs.

所以,这样做:

typedef struct _shape Shape; // Define _shape and Shape later

typedef void (*fptrSet)(Shape*, int);
typedef int  (*fptrGet)(Shape*);
typedef void (*fptrDisplay)();    

如果您的编译器不喜欢这样,您可能需要将其更改为:

typedef struct _shape; // Define _shape later

typedef void (*fptrSet)(struct _shape*, int);
typedef int  (*fptrGet)(struct _shape*);
typedef void (*fptrDisplay)();