Включая ‹termios.h› и ‹asm/termios.h› в одном проекте

Чего я хочу добиться: я хочу установить пользовательские значения baud rate для некоторых tty*-подобных UART-сопоставленных терминалов.

Как: единственный способ, который я нашел, — это использовать структуру struct termios2, которая находится в заголовке<asm/termios> (как уже упоминалось здесь, первый ответ).

Мое решение работает очень хорошо, но теперь мне нужно использовать некоторые функции:

speed_t cfgetispeed(const struct termios *);
int     tcdrain(int);
int     tcflow(int, int);
int     tcflush(int, int);
int     tcgetattr(int, struct termios *);
pid_t   tcgetsid(int);
int     tcsendbreak(int, int);
int     tcsetattr(int, int, struct termios *);

Проблема в том, что в <asm/termios.h> таких функций нет, и мне нужно включить <termios.h> для возможности их использования.

Проблема: если я включу оба заголовка (<asm/termios.h> и <termios.h>), компилятор будет кричать о переобъявлении функций и структур, и он прав.

Как я могу решить эту проблему, не используя какую-то непонятную практику (например, обернув один из заголовков в пространство имен, как упомянуто здесь)?


person bilserial    schedule 08.06.2016    source источник
comment
связанный вопрос от того же автора stackoverflow.com/questions/37697155/   -  person Patrick Trentin    schedule 08.06.2016
comment
Вы можете: 1) Обернуть заголовки в их собственных пространствах имен, 2) Рефакторировать ваш код, чтобы ни одна единица перевода не включала оба, 3) Включить <asm/termios.h> через прокси-заголовок, который скрывает конфликтующие определения с макросами. (2) это самый сложный способ. (3) по крайней мере так же неясно, как и (1), и это тоже хак.   -  person Mike Kinghan    schedule 10.06.2016


Ответы (2)


Как я могу решить эту проблему, не используя какую-то непонятную практику (например, обернув один из заголовков в пространство имен, как упомянуто здесь)?

Если вы обнаружите, что пространства имен неясны, я не знаю, как бы вы назвали это:

#define termios asmtermios
#include <asm/termios.h>
#undef  termios
#include <termios.h>

В любом случае, это тоже избавит вас от error: redefinition of 'struct termios'.

person Armali    schedule 30.01.2018
comment
Я бы назвал это решением! :) - person JakeSays; 18.07.2020

У меня была аналогичная проблема - мне нужна была поддержка пользовательской скорости передачи данных с такими определениями, как termios2, TCGETS2 и BOTHER, но при этом использовались традиционные вызовы termios. Я инстинктивно поместил материал termios2 в его собственный модуль компиляции, и проблем не возникло. Итак, моя структура выглядит так:

serial_driver.c/.h

#include <termios.h>
#include <fcntl.h>
#include <dirent.h>

int open_port(int fd, int baudrate, eParitySetting parity, int numStopBits)
{
  if(baudrate_is_non_standard(baudrate)
    setNonStandardBaudRateTermios(fd, baudrate, parity, numStopBits);
  else
    //all the normal tcgetattr/cfsetospeed/tcsetattr
}

int do_other_things(void)
{
  //all the normal tcsendbreak/tcflush/etc things
}

serial_driver_abr.c/.h

#include <asm/termios.h> /* asm gives us the all important BOTHER and TCGETS2 */
#include <fcntl.h>
#include <dirent.h>
#include <stropts.h> /* Oddly, for ioctl, because ioctl.h causes include dramas */

setNonStandardBaudRateTermios(int fd, int baudrate, eParitySetting parity, int numStopBits)
{
  //All the termios2/ioctl/TCGETS2/BOTHER things
}

Хорошо работает для меня.

person Heath Raftery    schedule 07.05.2019