В вашем заголовке измените
typedef my_type_t;
на
struct my_type_t;
Это довольно распространенный шаблон.Просто имейте в виду, что вам понадобится функция для выделения структуры в куче и ее освобождения;одна из частей информации, которую вы скрываете, - это размер структуры, поэтому потребитель API может иметь дело только с указателями на структуру, а не с самой структурой.
Идиоматический API будет выглядеть примерно так:
struct my_type_t* my_type_new(void);
void my_type_free(struct my_type_t* self);
my_type_init
обычно используется для инициализации уже выделенного экземпляра, что действительно полезно, если вы хотите связать его с помощью функции *_new
подтипа.
Редактировать : в ответ на ваш дополнительный вопрос вы можете сделать что-то подобное в заголовке:
#if !defined(MY_TYPE_NS)
# define MY_TYPE_NS struct
#endif
typedef MY_TYPE_NS my_type_t my_type;
my_type* my_type_new(void);
/* ... */
Затем в файле * .c:
#define MY_TYPE_NS union
#include "test.h"
union my_type_t {
/* ... */
};
my_type* my_type_new(void*) {
my_type* res = malloc(sizeof(my_type));
res->field = 42;
return res;
}
Который я считаю лишь слегка злым.Вероятно, я бы просто использовал объединение, вложенное в структуру, чтобы избежать неожиданностей в коде.