繁体   English   中英

typedef 结构导致“不允许不完整类型的指针”错误

[英]typedef struct leads to “pointer to incomplete type not allowed” error

我使用的库在其标头 ( http_client.h ) 中包含以下声明:

typedef struct _httpc_state httpc_state_t;

该库在实现中定义了结构 ( http_client.c )

typedef struct _httpc_state
{
  struct altcp_pcb* pcb;
  ip_addr_t remote_addr;
  u16_t remote_port;
  int timeout_ticks;
  struct pbuf *request;
  struct pbuf *rx_hdrs;
  u16_t rx_http_version;
  u16_t rx_status;
  altcp_recv_fn recv_fn;
  const httpc_connection_t *conn_settings;
  void* callback_arg;
  u32_t rx_content_len;
  u32_t hdr_content_len;
  httpc_parse_state_t parse_state;
#if HTTPC_DEBUG_REQUEST
  char* server_name;
  char* uri;
#endif
} httpc_state_t;

在同一个 C 文件中,它实现了以下使用结构体的函数:

/** http client tcp poll callback */
static err_t
httpc_tcp_poll(void *arg, struct altcp_pcb *pcb)
{
  /* implement timeout */
  httpc_state_t* req = (httpc_state_t*)arg; // Here the void pointer is casted to httpc_state_t
  LWIP_UNUSED_ARG(pcb);
  if (req != NULL) {
    if (req->timeout_ticks) { // Here the concrete type is used. Works. No problems.
      req->timeout_ticks--;
    }
    if (!req->timeout_ticks) {
      return httpc_close(req, HTTPC_RESULT_ERR_TIMEOUT, 0, ERR_OK);
    }
  }
  return ERR_OK;
}

我有一个使用这个库的 C++ 文件,当然包括所需的头文件 ( http_client.h )。

extern "C"
{
    #include "FreeRTOS.h"
    #include "task.h"
    #include "semphr.h"

    #include "lwip/tcpip.h"
    #include "lwip/apps/http_client.h"  // Here I include their http_client.h file

    #include "projdefs.h"
}

在我的下一个函数中,我需要完全按照他们的实现做。 我需要对httpc_state_t 我实现了他们的回调函数如下:

err_t rec_fn(void *arg, struct altcp_pcb *conn, struct pbuf *p, err_t err)
{
    if (p)
    {
        httpc_state_t* req = (httpc_state_t*)arg; // Compiler sees no problems in casting to my desired type....
        req->timeout_ticks = 30; // COMPILE ERROR, pointer to incomplete class type _httpc_state is not allowed 
    }
}

为什么我会收到那个编译错误?! 包括头文件。 头文件声明了 typedef。 即使在阅读了这个这个之后,我仍然不明白我做错了什么......

不完整类型意味着它已声明但未定义。 您需要在头文件中定义该结构并将其包含在您的 C 文件中。

在定义函数rec_fn的翻译单元中,编译器只能看到以下声明

typedef struct _httpc_state httpc_state_t;

它对这条语句中使用的数据成员timeout_ticks是否一无所知

req->timeout_ticks = 30;

确实在结构struct _httpc_state声明了它的类型。 即名称timeout_ticks在此翻译单元中未声明。 所以编译器会报错。

如果您打算在翻译单元中使用结构的数据成员,那么编译器需要知道它们的声明。 也就是说,您还需要包含结构定义。

如果允许,请在标题中移动结构定义,或者在定义函数的模块中复制其定义。

请注意,如果结构定义未放置在标题中,则原因可能是代码作者不想使其在其模块或库之外可用。

错误消息措辞不当。

指向不完整类型的指针很好! 取消引用不完整类型的成员是问题所在。

在发生错误时,编译器还没有“看到”该翻译单元中类型的完整定义。

它识别类型,但不知道该类型是否有成员timeout_ticks更不用说如何生成访问它的代码了。 [例如成员相对于对象开始的位置。]

指向不完整类型的指针是减少依赖性和代码耦合的有用方法。 如果代码只需要传递指向类型的指针,则可以声明(不完整)类型并帮助进行类型检查,但不会暴露给完整定义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM