Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define API in header and private fields in source in c

Tags:

c

struct

I want to define an API function in header file, and then implement it in source file.

Here is the hello.h, I want to define "world" in header:

typedef struct Hello {
    int (*world) (void);
} Hello;

Here is the hello.c, I want to implement "world" in source:

#include "hello.h"

struct Hello {
    int foo;
    int bar;
    int other;
    int fields;
    int many;
    int private;
    int only;
    int in_source_file;
    
    int (*world) (void);
};

Hello* hello = malloc(sizeof(Hello));
hello->foo = 1;

Here is the error in vscode:

struct "Hello" has no field "foo".

Is it possible in c? How to do if yes?

like image 750
stackbiz Avatar asked Oct 22 '25 23:10

stackbiz


1 Answers

as I said in a comment of your question :

you have two different definitions of Hello, this is not possible if the c file includes the header

and

I want to implement "world" in source

it seems you confuse implementation and initialization, only a function can be implemented in C


How to define API in header and private fields in source in c

If your goal is to hide some part of the definition to not allow a code including the header to use them, you can use a void * attribute and initialize/use it in your source.

Example in the header file :

/* ... */

typedef struct {
   void * internal;
   /* declare some 'public' fields as world if they exist */
} MyStruct;

MyStruct * createMyStruct();    /* malloc and init */
void freeMyStruct(MyStruct *);  /* purge and free */

/* to allow array of MyStruct */
void initializeMyStruct(MyStruct *); /* init only */
void purgeMyStruct(MyStruct *); /* free internal members, doesn't free arg */

/* declare some other 'public' functions */

/* ... */

and the source

#include <stdlib.h>
#include "MyStruct.h"

typedef struct {
  int foo;
  /* etc, fields 'private' for the users implementing MyStruct */
} MyStructInternal;

MyStruct * createMyStruct()
{
   MyStruct * s = malloc(sizeof(MyStruct));

   initializeMyStruct(s);
   return s;
}

void initializeMyStruct(MyStruct * s)
{
   s->internal = malloc(sizeof(MyStructInternal));
   ((MyStructInternal *) s->internal)->foo = 1;
   /* initializing r->internal other fields */
}

void freeMyStruct(MyStruct * s)
{
    purgeMyStruct(s);
    free(s);
}

void purgeMyStruct(MyStruct * s)
{
  free(s->internal);
}

/* implement other 'public' functions participating on the implementation of MyStruct */

/* other 'private' functions participating on the hidden implementation of MyStruct */

You must offer both the creating and deleting functions because the real definition being hidden the user cannot allocate and free a MyStruct by himself.

Obviously a simpler/better way is to move to C++ because in a way you define a class ;-)

like image 60
bruno Avatar answered Oct 25 '25 22:10

bruno



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!