Опустить явное приведение для структур с определенным типом - PullRequest
1 голос
/ 30 апреля 2019

Я хотел бы скрыть требование структуры OpenSSL RSA от моего заголовка API, поэтому я сделал:

// api.h

typedef struct RSA_key * RSA_key_ptr;

RSA_key_ptr get_rsa_key();
void free_rsa_key(RSA_key_ptr key);
// api.c

#include <openssl\rsa.h> // RSA struct

typedef RSA RSA_key;

RSA_key_ptr get_rsa_key()
{
  //return RSA_new();
    return (RSA_key_ptr)RSA_new();
}

void free_rsa_key(RSA_key_ptr key)
{
  //RSA_free(key);
    RSA_free((RSA*)key);
}

Моя проблема в том, что каждый раз, когда я ссылаюсь на RSAуказатель в api.c Мне нужно выполнить приведение к RSA* из RSA_key_ptr для предотвращения несовместимых типов указателей предупреждений.

Я хотел бы найти большеэлегантный способ:

  1. Избегать явных приведений
  2. Избегать предупреждений

1 Ответ

1 голос
/ 30 апреля 2019

Вам нужен актерский состав.struct RSA_key - это новый тип, который не определен typedef RSA RSA_key;.Это название несвязанной структуры без определения.Вы можете иметь дело только с указателями на него и приводить другие указатели структур к нему и из него.

Это неплохой способ скрыть детали реализации (за исключением лишних typedef RSA RSA_key;).И приведение является хорошим стандартом C.

Если вы попадаете в ситуации, когда для приведенных выражений требуется слишком много круглых скобок вокруг себя, то небольшая служебная функция или макрос могут помочь ее смягчить:

static inline RSA* as_rsa(struct RSA_key* rsa_key)
{ return (RSA*)rsa_key; }

static inline struct RSA_key* as_rsa_key(RSA* rsa_key)
{ return (struct RSA_key*)rsa_key; }
...