I'm trying to architect some C code such that the .c file and private .h file define a rather complex structure, but a public facing header file only requires pointers to that structure type. What I tried was this:
publicRadio.h
typedef struct _radio Radio;
void radioReceive(Radio *radio, ....);
privateRadio.h
#include <publicRadio.h>
struct _radio {
...
...
}
radio.c
#include <publicRadio.h>
#include <privateRadio.h>
void radioReceive(Radio *radio, ....)
{
...
}
When I try to compile this though, I get something like
radio.c:91:9: error: parameter 'radio' has just a forward declaration
radio.c:90:6: error: conflicting types for 'radioReceive'
publicRadio.h:29:6: note: previous declaration of 'radioReceive' was here
I'm trying to emulate the pattern I've seen in other libraries that have public facing APIs that expose their structures through functions, but hide the gory details. What is the recipe one uses to accomplish that?
In computer programming, an opaque pointer is a special case of an opaque data type, a data type declared to be a pointer to a record or data structure of some unspecified type. Opaque pointers are present in several programming languages including Ada, C, C++, D and Modula-2.
In computer science, an opaque data type is a data type whose concrete data structure is not defined in an interface. This enforces information hiding, since its values can only be manipulated by calling subroutines that have access to the missing information.
Opaque pointers are used to represent C pointers to types that cannot be represented in Swift, such as incomplete struct types.
An opaque object and its handle are significant only at the process where the object was created, and cannot be transferred to another process. MPI provides certain predefined opaque objects and predefined, static handles to these objects. Such objects may not be destroyed.
This pattern is normally implemented like this:
radio.h
#ifndef RADIO_H
#define RADIO_H
typedef struct _radio Radio;
void radioReceive(Radio *radio, ....);
#endif
radio.c
#include "radio.h"
struct _radio {
// _radio struct implementation
};
void radioReceive(Radio *radio, ....) {
// radioReceive implementation
}
main.c
#include "radio.h"
.... // use Radio, radioReceive, etc.
OK: The following does work on both MSVC and GCC without problems.
The two important errors were:
Here is the code I used:
publicRadio.h
typedef struct _radio Radio;
void radioReceive(Radio *radio, ....);
privateRadio.h
#include "publicRadio.h"
struct _radio {
...
...
};
radio.c
#include "privateRadio.h"
void radioReceive(Radio *radio, ....)
{
...
}
main.c
#include "publicRadio.h"
void main()
{
Radio* radio = ...;
radioReceive(radio, ....);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With