Typedef против структуры контейнера для абстракции платформы?

#c #struct #cross-platform #typedef

#c #структура #кросс-платформенный #typedef

Вопрос:

Я работаю над небольшим уровнем абстракции платформы, который я намерен использовать в качестве основы для будущих проектов. Первоначально я следовал примеру SDL и динамически выделял структуру контейнера.

Например, в общедоступном заголовке:

 typedef struct MY_MUTEX MY_MUTEX;
  

В исходном файле для Windows:

 struct MY_MUTEX {
    HANDLE handle;
};

MY_MUTEX *MY_CreateMutex() {
    MY_MUTEX *m = malloc(sizeof(MY_MUTEX));
    ...
    m->handle = CreateMutex(NULL, FALSE, NULL);
    ...
}
  

Но потом я начал задаваться вопросом, могу ли я вообще отказаться от выделения памяти и использовать только typedef тип, зависящий от платформы:

 #ifdef _WIN32
typedef HANDLE MY_MUTEX;
#else
typedef pthread_mutex_t MY_MUTEX;
#endif
  

Мне кажется хорошей идеей избегать ненужных выделений памяти, но какие проблемы (если таковые имеются) может вызвать этот простой typedef метод? Я бы пожертвовал большой гибкостью?

Ответ №1:

Вы можете использовать typedef структуру контейнера или даже макросы — любой из них подойдет. Даже смесь подойдет. Важно то, что ваша абстракция ведет себя согласованно на разных платформах, независимо от того, какая базовая реализация используется — и это может сделать некоторые варианты неподходящими для некоторых случаев.

Например, может быть нецелесообразно использовать simple typedef для имитации объекта события Windows в Unix, поэтому вы можете использовать структуру контейнера для событий… но это не должно мешать вам использовать a typedef для мьютексов, если этого достаточно для того, как мьютексы будут использоваться через вашу абстракцию.

Я уверен, что есть те, кто предпочел бы придерживаться одного подхода для всего API, но я не вижу в этом необходимости, пока абстракция появляется и ведет себя последовательно от одной платформы к другой.

В принципе, выбирайте самую легкую вещь, которая работает в каждом конкретном случае.