Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using C struct without including header file

My basic problem is that I want to use some structs and functions defined in a header file by not including that header file in my code.

The header file is generated by a tool. Since I don't have access to the header file, I can't include it in my program.

Here's a simple example of my scenario:

first.h

#ifndef FIRST_H_GUARD
#define FIRST_H_GUARD
typedef struct ComplexS {
   float real;
   float imag;
} Complex;

Complex add(Complex a, Complex b);

// Other structs and functions
#endif

first.c

#include "first.h"

Complex add(Complex a, Complex b) {
   Complex res;
   res.real = a.real + b.real;
   res.imag = a.imag + b.imag;
   return res;
}

my_program.c

// I cannot/do not want to include the first.h header file here
// but I want to use the structs and functions from the first.h
#include <stdio.h>

int main() {
   Complex a; a.real = 3; a.imag = 4;
   Complex b; b.real = 6; b.imag = 2;

   Complex c = add(a, b);
   printf("Result (%4.2f, %4.2f)\n", c.real, c.imag);

   return 0;
}

My intention is to build an object file for my_program and then use the linker to link up the object files into an executable. Is what I want to achieve possible in C?

like image 560
shams Avatar asked Dec 23 '22 02:12

shams


2 Answers

In order to use the struct in my_program.c, the struct has to be defined in my_program.c. There's no way around it.

In order to define it, you have to either include first.h or provide a definition of Complex in my_program.c in some other way (like copy-paste the definition of Complex into my_program.c).

If your first.h looks as you posted, then there's no point in doing any copy-pasting, of course, since it is going to be the same thing anyway. Just include your first.h.

If you don't want to include first.h because of something else in that header (which you don't show here), you can move the definition of Complex into a separate small header, and include it instead in both places.

like image 76
AnT Avatar answered Dec 28 '22 05:12

AnT


I modified the files to use pointers and forward references and got it to work.

I'm now going to inspect the generated header file to see if I need to use any function that does not accept pointers as arguments.

Here's the code I ended up trying:

first.h

#ifndef FIRST_H_GUARD
#define FIRST_H_GUARD
typedef struct ComplexS {
   float real;
   float imag;
} Complex;

Complex* new_complex(float a, float b);
Complex* add(Complex* a, Complex* b);
void print_complex(Complex* a);
#endif

first.c

#include <stdio.h>
#include <stdlib.h>
#include "first.h"

Complex* new_complex(float a, float b) {
   Complex* temp = (Complex*)malloc(sizeof(Complex));
   temp->real = a;
   temp->imag = b;
   return temp;
}

Complex* add(Complex* a, Complex* b) {
   Complex *res = new_complex(a->real + b->real, a->imag + b->imag);
   return res;
}

void print_complex(Complex* a) {
   printf("Complex(%4.2f, %4.2f)\n", a->real, a->imag);
}

second.c

#include <stdio.h>

struct ComplexS; // forward declaration
typedef struct ComplexS Complex; 

Complex* new_complex(float a, float b); 
Complex* add(Complex* a, Complex* b); 
void print_complex(Complex* a);

int main() {
   Complex* a = new_complex(3, 4);
   Complex* b = new_complex(6, 2);

   Complex* c = add(a, b);
   print_complex(c);

   return 0;
}

output:

Complex(9.00, 6.00)
like image 22
shams Avatar answered Dec 28 '22 05:12

shams