function pointer and function is incompatible because of arguments - c

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

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

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.
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)();

Related

How to pass the variable address of the structure short name to a function

How can I pass the variable address of the structure short name (color) to a function (fun) arguments.
#include <stdio.h>
void fun();
struct figure {
char name[30];
float field;
} color;
int main(void) {
fun();
return 0;
}
How to pass the variable address of the structure short name
To pass the address you only need &color.
Then the function needs to accept a pointer to struct figure.
It may look like:
#include <stdio.h>
#include <string.h>
struct figure{
char name[30];
float field;
} color;
void fun(struct figure *); // Function takes pointer to struct figure
int main(void){
strcpy(color.name, "Joe"); // Initialize color
color.field = 42.0;
fun(&color); // Pass address of color
return 0;
}
void fun(struct figure *c)
{
printf("%s\n", c->name); // Access color using the passed pointer
printf("%f\n", c->field);
}
Output:
Joe
42.000000
struct figure { ... }; would just introduce a new type named struct figure, whereas struct figure { ... } color; does two things (1) introduce above mentioned type and (2) define a variable named color of that type.
To pass an object of type struct figure to a function, write...
struct figure{
char name[30];
float field;
} color;
void fun(struct figure f) {
printf("%s %f\n", f.name, f.field);
}
int main(void){
struct figure myObj;
strcpy(myObj.name, "Hello!");
myObj.field = 1.0;
fun(myObj);
return 0;
}
You could also pass the address of such an object, which would then allow the function to alter the originally passed object as well:
void fun(struct figure *f) {
f->field = 2.0
printf("%s %f\n", f->name, f->field);
}
int main() {
...
fun(&myObj);

Parameter passing multiple values using void pointer

I want to pass multiple arguments to a function using a void pointer.
void* function(void *params)
{
//casting pointers
//doing something
}
int main()
{
int a = 0
int b = 10;
char x = 'S';
void function(???);
return 0;
}
I know that I have to cast them to a certain variable in my function but I do not know how I can pass my 3 arguments as one void pointer to my function.
I have searched for this problem know quite some time but I could not find anything that would help me.
You could do it like this:
struct my_struct
{
int a;
int b;
char x;
}
void * function(void * pv)
{
struct my_strcut * ps = pv; /* Implicitly converting the void-pointer
/* passed in to a pointer to a struct. */
/* Use ps->a, ps->b and ps->x here. */
return ...; /* NULL or any pointer value valid outside this function */
}
Use it like this
int main(void)
{
struct my_struct s = {42, -1, 'A'};
void * pv = function(&s);
}
Following up on the OP's update:
struct my_struct_foo
{
void * pv1;
void * pv2;
}
struct my_struct_bar
{
int a;
int b;
}
void * function(void * pv)
{
struct my_strcut_foo * ps_foo = pv;
struct my_struct_bar * ps_bar = ps_foo->pv1;
/* Use ps_foo->..., ps_bar->... here. */
return ...; /* NULL or any pointer value valid outside this function */
}
Use it like this
int main(void)
{
struct my_struct_bar s_bar = {42, -1};
struct my_struct_foo s_foo = {&s_bar, NULL};
void * pv = function(&s_foo);
}
The void* is used as a pointer to a "generic" type. Hence, you need to create a wrapping type, cast convert to void* to invoke the function, and cast convert back to your type in the function's body.
#include <stdio.h>
struct args { int a, b; char X; };
void function(void *params)
{
struct args *arg = params;
printf("%d\n", arg->b);
}
int main()
{
struct args prm;
prm.a = 0;
prm.b = 10;
prm.X = 'S';
function(&prm);
return 0;
}

Emulating Classes in C using Structs

I am constrained to using C for a competition and I have a need to emulate classes. I am trying to construct a simple "point" class that can return and set the X and Y coordinates of a point. Yet, the below code returns errors such as "unknown type name point", "expected identifier or (" and "expected parameter declarator." What do these errors mean? How do I correct them? Is this the correct approach to writing a "pseudo-class"?
typedef struct object object, *setCoordinates;
struct object {
float x, y;
void (*setCoordinates)(object *self, float x, float y);
void (*getYCoordinate)(object *self);
void (*getXCoordinate)(object *self);
};
void object_setCoordinates(object *self, float x, float y){
self->x = x;
self->y = y;
}
float object_getXCoordinate(object *self){
return self->x;
}
float object_getYCoordinate(object *self){
return self->y;
}
object point;
point.setCoordinates = object_setCoordinates;
point.getYCoordinate = object_getYCoordinate;
point.getXCoordinate = object_getXCoordinate;
point.setCoordinates(&point, 1, 2);
printf("Coordinates: X Coordinate: %f, Y Coordinate: %f", point.getXCoordinate, point.getYCoordinate);
Reference:
1. C - function inside struct
2. How do you implement a class in C?
You would do much better to implement it as follows:
#include <stdio.h>
struct point {
float x;
float y;
};
void point_setCoordinates(struct point *self, float x, float y){
self->x = x;
self->y = y;
}
float point_getXCoordinate(struct point *self){
return self->x;
}
float point_getYCoordinate(struct point *self){
return self->y;
}
int main(void) {
struct point my_point;
point_setCoordinates(&my_point, 1, 2);
printf("Coordinates: X Coordinate: %f, Y Coordinate: %f\n",
point_getXCoordinate(&my_point),
point_getYCoordinate(&my_point));
return 0;
}
A few things to note:
As #Olaf has pointed out, never typedef a pointer - it hides your intent and makes things unclear. Yes, it's all over poor APIs (e.g: Windows), but it reduces readability.
You really don't need these functions to be the equivalent to virtual functions... just have a set of point_*() functions that you call on the point 'thing'.
Don't confuse things with poor names... if it's an X,Y point, then call it such - not an object (which is a very generic concept).
You need to call functions... in your call to printf() you used point.getXCoordinate - that is to say you took it's address and asked printf() to display it as though it were a float
You might start to wonder why you'd care about calling a function to get access to a variable that is inside a transparent struct... See below.
Many libraries / APIs provide opaque datatypes. This means that you can get a 'handle' to a 'thing'... but you have no idea what's being stored within the 'thing'. The library then provides you with access functions, as shown below. This is how I'd advise you approach the situation.
Don't forget to free the memory!
I've implemented an example below.
point.h
#ifndef POINT_H
#define POINT_H
struct point;
struct point *point_alloc(void);
void point_free(struct point *self);
void point_setCoordinates(struct point *self, float x, float y);
float point_getXCoordinate(struct point *self);
float point_getYCoordinate(struct point *self);
#endif /* POINT_H */
point.c
#include <stdlib.h>
#include <string.h>
#include "point.h"
struct point {
float x;
float y;
};
struct point *point_alloc(void) {
struct point *point;
point = malloc(sizeof(*point));
if (point == NULL) {
return NULL;
}
memset(point, 0, sizeof(*point));
return point;
}
void point_setCoordinates(struct point *self, float x, float y) {
self->x = x;
self->y = y;
}
float point_getXCoordinate(struct point *self) {
return self->x;
}
float point_getYCoordinate(struct point *self) {
return self->y;
}
void point_free(struct point *self) {
free(self);
}
main.c
#include <stdio.h>
#include "point.h"
int main(void) {
struct point *point;
point = point_alloc();
point_setCoordinates(point, 1, 2);
printf("Coordinates: X Coordinate: %f, Y Coordinate: %f\n",
point_getXCoordinate(point),
point_getYCoordinate(point));
point_free(point);
return 0;
}
Your code has some minor errors. That's why it doesn't compile.
Fixed here:
typedef struct object object;
struct object {
float x, y;
void (*setCoordinates)(object *self, float x, float y);
float (*getYCoordinate)(object *self);
float (*getXCoordinate)(object *self);
};
void object_setCoordinates(object *self, float x, float y){
self->x = x;
self->y = y;
}
float object_getXCoordinate(object *self){
return self->x;
}
float object_getYCoordinate(object *self){
return self->y;
}
int main()
{
object point;
point.setCoordinates = object_setCoordinates;
point.getYCoordinate = object_getYCoordinate;
point.getXCoordinate = object_getXCoordinate;
point.setCoordinates(&point, 1, 2);
printf("Coordinates: X Coordinate: %f, Y Coordinate: %f",
point.getXCoordinate(&point), point.getYCoordinate(&point));
}
As for the approach, there's probably no need to store the pointers to your methods inside the struct when you can simply call them directly:
object x;
object_setCoordinates(x, 1, 2);
//...
I also have an example of basic class emulation in C [the OP specified for a specific application, although, this answer is to the general question]:
A header file called "c_class.h"
#ifndef CLASS_HEADER_H
#define CLASS_HEADER_H
// Function pointer prototypes used by these classes
typedef int sub_func_t (int);
typedef float sub_funcf_t (int,int);
/* class type definition
(emulated class type definition; C doesn't really have class types) */
typedef struct {
//Data Variables
int a;
/*Function (also known as Method) pointers
(note that different functions have the same function pointer prototype)*/
sub_func_t* add;
sub_func_t* subt;
sub_func_t* mult;
sub_funcf_t* div;
} class_name;
// class init prototypes
// These inits connect the function pointers to specific functions
// and initialize the variables.
class_name* class_init_ptr (int, sub_func_t*, sub_func_t*, sub_func_t*, sub_funcf_t*);
class_name class_init (int, sub_func_t*, sub_func_t*, sub_func_t*, sub_funcf_t*);
#endif
A source code file called "c_class.c"
//gcc -o c_class c_class.c
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"c_class.h"
// The class function definitions.
/*
If we make these member functions static then they are only
accessible via code from this file.
However, we can still pass the class-like objects around a
larger program and access their member functions,
just like in any OO language.
It is possible to emulate inheritance by declaring a class object
from the class type definition (I don't touch on these more
abstract subjects though, this is only a basic class emulation).
*/
static int AddFunc(int num){
num++;
return num;
}
static int SubtFunc(int num){
num--;
return num;
}
static int MultFunc(int num){
num *= num;
return num;
}
static float DivFunc(int num, int denom){
float fnum = (float)num / (float)denom;
return fnum;
}
// The class init function definitions.
class_name* class_init_ptr (int num, sub_func_t* addition, sub_func_t* subtraction, sub_func_t* multiplication, sub_funcf_t* division)
{
class_name* new_class = malloc(sizeof(*new_class));
assert(new_class != NULL);
*new_class = (class_name){num, addition, subtraction, multiplication, division};
/*We could also just type:
new_class->a = num;
new_class->add = addition;
new_class->subt = subtraction;
new_class->mult = multiplication;
new_class->div = division;
*/
return new_class;
}
class_name class_init(int num, sub_func_t* addition, sub_func_t* subtraction, sub_func_t* multiplication, sub_funcf_t* division)
{
class_name new_class;
new_class = (class_name){num, addition, subtraction, multiplication, division};
/* We could also just type:
new_class.a = num;
new_class.add = addition;
new_class.subt = subtraction;
new_class.mult = multiplication;
new_class.div = division;
*/
return new_class;
}
//Working Function Prototypes
class_name* Working_Function(class_name*);
class_name Working_Function_Two(class_name);
int main(){
/* It's possible to connect the functions within the init also,
w/o sending them. */
class_name *MyClass = class_init_ptr(5, AddFunc, SubtFunc, MultFunc, DivFunc);
class_name MyOtherClass = class_init(0, AddFunc, SubtFunc, MultFunc, DivFunc);
printf("%i\n",MyClass->add(100));// 101
printf("%i\n",MyClass->subt(100));// 99
printf("%i\n",MyClass->mult(100));// 10000
printf("%f\n",MyClass->div(MyClass->a,2)); // 2.5
printf("%i\n",MyClass->mult(MyClass->mult(100))); //100000000
MyClass = Working_Function(MyClass);
//This would work also (because we're passing a pointer):
//Working_Function(MyClass);
printf("%i\n",MyClass->a); //a = 5000
MyOtherClass = Working_Function_Two(MyOtherClass);
printf("%i\n",MyOtherClass.a); //a = 9999
MyOtherClass.a = 25;
Working_Function_Two(MyOtherClass); //pass by value
printf("%i\n",MyOtherClass.a); //a = 25 (no value change)
Working_Function(&MyOtherClass); //pass by reference
printf("%i\n",MyOtherClass.a); //a = 5000 (value changed)
return 0;
}
//Working Functions
class_name* Working_Function(class_name* PassedClass){
printf("%i\n",PassedClass->a);// 5, then 25
printf("%i\n",PassedClass->add(PassedClass->a));// 6, then 26
PassedClass->a = 5000;
return PassedClass;
}
class_name Working_Function_Two(class_name PassedClass){
printf("%i\n",PassedClass.a);// 0, then 25
printf("%i\n",PassedClass.add(PassedClass.a));// 1, then 26
PassedClass.a = 9999;
return PassedClass;
}
/* We're passing emulated class objects and emulated class pointers
by reference and value, if everything works it should print this:
101
99
10000
2.500000
100000000
5
6
5000
0
1
9999
25
26
25
25
26
5000
*/
Another way to write a pseudo-class that needs polymorphism, with less overhead per instance, is to create a single virtual function table and have your constructor or factory function set that. Here’s a hypothetical example. (Edit: Now a MCVE, but for real code, refactor into header and separate source files.)
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
struct point; // Abstract base class.
struct point_vtable {
void (*setCoordinates)(struct point *self, float x, float y);
float (*getYCoordinate)(const struct point *self);
float (*getXCoordinate)(const struct point *self);
};
typedef struct point {
const struct point_vtable* vtable;
} point;
typedef struct cartesian_point {
const struct point_vtable* vtable;
float x;
float y;
} cartesian_point;
typedef struct polar_point {
const struct point_vtable* vtable;
float r;
float theta;
} polar_point;
void cartesian_setCoordinates( struct point* self, float x, float y );
float cartesian_getXCoordinate(const struct point* self);
float cartesian_getYCoordinate(const struct point* self);
void polar_setCoordinates( struct point* self, float x, float y );
float polar_getXCoordinate(const struct point* self);
float polar_getYCoordinate(const struct point* self);
const struct point_vtable cartesian_vtable = {
.setCoordinates = &cartesian_setCoordinates,
.getXCoordinate = &cartesian_getXCoordinate,
.getYCoordinate = &cartesian_getYCoordinate
};
const struct point_vtable polar_vtable = {
.setCoordinates = &polar_setCoordinates,
.getXCoordinate = &polar_getXCoordinate,
.getYCoordinate = &polar_getYCoordinate
};
void cartesian_setCoordinates( struct point* const self,
const float x,
const float y )
{
assert(self->vtable == &cartesian_vtable);
struct cartesian_point * const this = (struct cartesian_point*)self;
this->x = x;
this->y = y;
}
float cartesian_getXCoordinate(const struct point* const self)
{
assert(self->vtable == &cartesian_vtable);
const struct cartesian_point * const this = (struct cartesian_point*)self;
return this->x;
}
float cartesian_getYCoordinate(const struct point* const self)
{
assert(self->vtable == &cartesian_vtable);
const struct cartesian_point * const this = (struct cartesian_point*)self;
return this->y;
}
void polar_setCoordinates( struct point* const self,
const float x,
const float y )
{
assert(self->vtable == &polar_vtable);
struct polar_point * const this = (struct polar_point*)self;
this->theta = (float)atan2((double)y, (double)x);
this->r = (float)sqrt((double)x*x + (double)y*y);
}
float polar_getXCoordinate(const struct point* const self)
{
assert(self->vtable == &polar_vtable);
const struct polar_point * const this = (struct polar_point*)self;
return (float)((double)this->r * cos((double)this->theta));
}
float polar_getYCoordinate(const struct point* const self)
{
assert(self->vtable == &polar_vtable);
const struct polar_point * const this = (struct polar_point*)self;
return (float)((double)this->r * sin((double)this->theta));
}
// Suitable for the right-hand side of initializations, before the semicolon.
#define CARTESIAN_POINT_INITIALIZER { .vtable = &cartesian_vtable,\
.x = 0.0F, .y = 0.0F }
#define POLAR_POINT_INITIALIZER { .vtable = &polar_vtable,\
.r = 0.0F, .theta = 0.0F }
int main(void)
{
polar_point another_point = POLAR_POINT_INITIALIZER;
point* const p = (point*)&another_point; // Base class pointer.
polar_setCoordinates( p, 0.5F, 0.5F ); // Static binding.
const float x = p->vtable->getXCoordinate(p); // Dynamic binding.
const float y = p->vtable->getYCoordinate(p); // Dynamic binding.
printf( "(%f, %f)\n", x, y );
return EXIT_SUCCESS;
}
This takes advantage of the guarantee that the common initial subsequence of structs can be addressed through a pointer to any of them, and stores only one pointer of class overhead per instance, not one function pointer per virtual function. You can use the virtual table as your class identifier for your variant structure. Also, the virtual table cannot contain garbage. Virtual function calls need to dereference two pointers rather than one, but the virtual table of any class in use is highly likely to be in the cache.
I also note that this interface is very skeletal; it’s silly to have a polar class that can do nothing but convert back to Cartesian coordinates, and any implementation like this would at minimum need some way to initialize dynamic memory.
If you don’t need polymorphism, see Attie’s much simpler answer.

get size of hidden struct C

I'm trying to get the size of a struct that was defined in a different source file (other.c) to keep it hidden.
In the other.h:
typedef struct X x_t;
In the other.c:
struct X{
int y;
int z;
};
Now I want in the main.c to get the size of this struct.
#include "other.h"
int main(){
x_t *my_x;
my_x = malloc(sizeof(struct x_t));
return 0;}
But this gives me following error:
error: invalid application of ‘sizeof’ to incomplete type ‘struct x_t’
Can anybody help me? Thank you!
The whole purpose of having a hidden struct is to carefully control their construction, their destruction, and access to the contents.
Functions to construct, destruct, get the contents, and set the contents have to be provided to make the hidden struct useful.
Here's an example of what the .h and .c files could be:
other.h:
typedef struct X x_t;
x_t* construct_x(void);
void destruct_x(x_t* x);
void set_y(x_t* x, int y);
int get_y(x_t* x);
void set_z(x_t* x, int z);
int get_z(x_t* x);
other.c:
struct X {
int y;
int z;
};
x_t* construct_x(void)
{
return malloc(sizeof(x_t));
}
void destruct_x(x_t* x)
{
free(x);
}
void set_y(x_t* x, int y)
{
x->y = y;
}
int get_y(x_t* x)
{
return x->y;
}
void set_z(x_t* x, int z)
{
x->z = z;
}
int get_z(x_t* x)
{
rteurn x->z;
}

Declaring struct attribute with different type

I have a struct that contain an attribute that can take many types,
I want ask about the most appropriate way to declare this attribute.
Example:
struct
{
void* pShape; //poiter to the shape that will be casted on *tCircle or *tRectangle
int type;//type of the shape
int h;
int l;
}tImage;
struct{
int size;
int r;
HANDLE calcul;
}tCircle
struct{
int size;
int x;
int y;
HANDLE calcul;
}tRectangle;
As you see here i'am using void* to declare a pointer to the shape and use type attribute to guess the type of the shape.
this is my function for the calcuation of the size of the shape in an image
int Image_Get_ShapeSize(tImage Im)
{
switch (Im.type)
{
case CIRCLE:
((tCircle*)(Im.shape))->calcul();
break;
case RECTANGLE:
((tRectangle*)(Im.shape))->calcul();
break;
default:
break;
}
}
what do you think about this is it a good method ?
I do not understand well why you need the tCircle and tRectangle structures because they have the same fields. I suggest you use only one definition and initialize the function pointer to a different and specific method.
struct shape {
int size;
int x;
int y;
void (*calcul) (struct shape * shape);
};
And then the specific functions:
void circle_calcul(struct shape * shape)
{
...
}
void rectangle_calcul(struct shape * shape)
{
...
}
And finally:
struct shape circle;
struct shape rectangle;
circle.calcul = circle_calcul;
rectangle.calcul = rectangle_calcul;

Resources