【发布时间】:2021-09-01 03:29:18
【问题描述】:
我正在使用一个在其标头 (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。即使在阅读了this 和this 之后,我仍然看不到我做错了什么......
【问题讨论】:
-
httpc_state_t尚未在.h文件中定义,因此您无法访问其成员。这可能是不透明指针的示例指针,这意味着 libaray 故意禁止您直接使用httpc_state_t的成员。寻找任何可以帮助您设置timeout_ticks的辅助函数。 -
库的意图可能是您应该不访问代码中结构的成员。假设您指的是github.com/RT-Thread/IoT_Board/blob/master/rt-thread/components/…,则
httpc_state_t类型的结构由httpc_init_connection_common分配和初始化。这包括timeout_ticks的值。为什么需要修改库的内部数据? -
@Bodo (and mediocrevegetable) 感谢您的 cmets。我想你是对的,他们不希望我更改数据。问题是,我正在下载一个“大”文件(512KB)作为测试,这需要的时间超过了超时允许的时间。我希望 http_client 会在下载仍在进行并且正在接收数据包时重置计时器。但在他们的库中,超时计数器只会减少。我找不到任何帮助函数或任何可以让我控制这种行为的东西
-
我注释掉了减少计数器的行(给了我一个无限超时),然后下载一直没有任何问题。但我一定是错过了什么。他们实施该机制当然是有原因的......
标签: c struct typedef definition incomplete-type