example - typedef struct c ejemplo
Ocultando la definiciĆ³n de C struct (4)
Las otras respuestas cubren tu problema bastante bien. Sin embargo, permítanme agregarles y responder a su último comentario:
Estoy obteniendo un error de compilación: en public.h: redefinición de typedef PRIVATE _...
Si bien el error se explica por sí mismo, probablemente sea menos claro por qué está sucediendo eso. Considere lo que sucede cuando incluye public.h:
#include "struct.h"
#include "func.h"
typedef struct _my_private_struct PRIVATE_;
Si rastrea esto y expande completamente el preprocesador, esto es lo que obtendrá:
// struct.h
struct _my_private_struct
{
int i;
};
// func.h
typedef struct _my_private_struct PRIVATE_;
extern PRIVATE_ * get_new(int);
// public.h
typedef struct _my_private_struct PRIVATE_;
Ahora debería ser obvio por qué estás teniendo problemas. Sin el typedef en func.h, tu get_new
prototype falla porque aún no se ha visto PRIVATE
. OTOH, si dejas el typedef, lo has definido dos veces.
Además, parece que estás tratando de mantener esa estructura privada de otros códigos y módulos. Incluso si arreglas los errores de compilación, realmente no has logrado esa encapsulación. Considera esto:
int main()
{
PRIVATE_ *p = get_new(2);
p->i = 1337; // HAHA, I just modified your private i.
// what are you going to do about it?
}
Si desea privacidad de datos en C, considere un diseño de puntero opaco. Recomiendo reestructurar su fuente de esta manera:
// public.h
#ifndef PUBLIC_H_
#define PUBLIC_H_
#include "func.h"
#endif
// func.h
#ifndef FUNC_H_
#define FUNC_H_
struct PRIVATE_NOT_ACCESSIBLE;
typedef struct PRIVATE_NOT_ACCESSIBLE myint_t;
// declare your struct methods here
myint_t* get_new(int);
// ..
#endif
// func.c
#include <stdlib.h>
#include "func.h"
// define this only with functions
// that''s suppose to work with its internal data
struct PRIVATE_NOT_ACCESSIBLE
{
int i;
};
myint_t * get_new(int i)
{
// ...
}
Ahora si intentas esto:
#include "public.h"
int main()
{
myint_t *p = get_new(2);
p->i = 1337; // Aw, doesn''t work anymore :(
}
Editar: para responder el comentario de OP a continuación.
Si tiene métodos de struct privados implementados en más de una unidad de compilación, puede hacerlo funcionar moviendo la definición de private a un encabezado dedicado:
// func_implementation.h
#include "func.h"
struct PRIVATE_NOT_ACCESSIBLE
{
int i;
};
// internal methods, helper functions you don''t want exposed should go here too.
// eg.
void helper_method(myint_t *);
Los archivos fuente que implementan su ''objeto'' privado de estructura incluirán ''func_implementation.h''. El código de cliente externo que usa privado incluirá solamente ''func.h''.
He aquí mi arreglo:
En public.h:
#ifndef PUBLIC_H_
#define PUBLIC_H_
#include "func.h"
/*extern typedef struct _my_private_struct PRIVATE_;*/
typedef struct _my_private_struct PRIVATE_; /* Thanks to larsmans and Simon Richter */
#endif
En struct.h
#ifndef STRUCT_H_
#define STRUCT_H_
struct _my_private_struct {
int i;
};
#endif
En func.h:
#ifndef FUNC_H_
#define FUNC_H_
#include "struct.h"
/* typedef struct _my_private_struct PRIVATE_; */
extern PRIVATE_ * get_new(int);
#endif
En func.c:
#include <stdlib.h>
#include "func.h"
PRIVATE_ * get_new(int i)
{
PRIVATE_ *p = (PRIVATE_ *) malloc(sizeof(PRIVATE_));
if (p == NULL) return NULL;
p->i = i;
return p;
}
En main.c:
#include "public.h"
int main(int argc, char ** argv)
{
PRIVATE_ *p = get_new(2);
return 0;
}
Cuando compilo esos archivos con GCC obtengo este error:
ANTIGUO ERROR COMPILE
múltiples clases de almacenamiento en especificadores de declaración
COMPILAR EL ERROR DESPUÉS DE EDITAR
esperado ''='', '','', '';'', ''asm'' o ''__attribute__'' antes de ''*'' token
¿Puede alguien ayudarme / explicarme por qué estoy recibiendo esto y cómo solucionarlo?
Hay un '';'' falta después de typedef.
EDITAR:
struct _my_private_struct {...};
No use nombres con un subrayado inicial. Están reservados para el idioma o la implementación.
La sintaxis actual es incorrecta, necesita poner un punto y coma después de los tiposdefs y las estructuras.
- Debe finalizar una instrucción
typedef
con a;
-
extern typedef
no tiene sentido, solo haz untypedef
.