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

时间:2022-07-06 16:04:29

I have read the book Understanding and Using C Pointers and try to compile the code below. But after compiling I got the warning: assignment from incompatible pointer type.

我读过“理解和使用C指针”一书,并尝试编译下面的代码。但是在编译之后我得到了警告:从不兼容的指针类型分配。

I have checked the code and find out the function pointer fptrSet and function ShapeSetX is incompatible because the first argument of fptrSet is void * and function ShapeSetX is Shape *.

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

How can I fix this? Thanks!

我怎样才能解决这个问题?谢谢!

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;
}

2 个解决方案

#1


1  

You have to respect pointer definition: pointer need that first parameter is a pointer to void, so your function implementation should have first parameter as void:

你必须尊重指针定义:指针需要第一个参数是一个指向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;
} 

#2


1  

I was going to say "Why don't you replace void with Shape then?", until I realised that Shape hadn't been defined yet - nor could you swap the two definitions, because Shape needs vFunc which needs the typedefs.

我打算说“你为什么不用Shape替换void呢?”,直到我意识到还没有定义Shape - 你也不能交换这两个定义,因为Shape需要vFunc,它需要typedef。

So, do this:

所以,这样做:

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

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

If your compiler doesn't like that, you may need to change it to:

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

typedef struct _shape; // Define _shape later

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

#1


1  

You have to respect pointer definition: pointer need that first parameter is a pointer to void, so your function implementation should have first parameter as void:

你必须尊重指针定义:指针需要第一个参数是一个指向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;
} 

#2


1  

I was going to say "Why don't you replace void with Shape then?", until I realised that Shape hadn't been defined yet - nor could you swap the two definitions, because Shape needs vFunc which needs the typedefs.

我打算说“你为什么不用Shape替换void呢?”,直到我意识到还没有定义Shape - 你也不能交换这两个定义,因为Shape需要vFunc,它需要typedef。

So, do this:

所以,这样做:

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

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

If your compiler doesn't like that, you may need to change it to:

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

typedef struct _shape; // Define _shape later

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