2

我刚刚回到 C 编程领域,我遇到了一个我认为与链接器相关的问题。

我也是第一次使用 cmake,所以这可能会增加我的挫败感。

我已经包含了一个第三方头文件,其中包含我的代码尝试使用的 typedef,它有这一行:

typedef struct pcap pcap_t;

所以我的代码有

pcap_t *var;
//later.....
var->fd;// this line throws the error

抛出

error: dereferencing pointer to incomplete type

那么我只是缺少另一个包含文件,还是这是链接器问题?我正在 QtCreator 中构建此代码并使用 cmake。我可以深入 a_t 以查看包含的标头中的 typedef 声明,但我似乎无法深入“struct a”本身以查看它的来源。

谢谢

编辑了上面的代码以反映我正在使用 pcap 库

所以我在源文件的头文件中包含了以下几行

#include <net/bpf.h>
#include <pcap/pcap.h>

所以我猜这两个包括之间,我错过了 pcap 结构的定义。我在哪里可以找到它?

谢谢

4

1 回答 1

4

typedef声明做了两件事。它声明了某种类型的存在struct a。它还声明 thata_tstruct a. 在没有任何信息来确定其大小的情况下声明类型的存在被 C 语言称为不完整类型。该声明通俗地称为前向声明,并且该类型通俗地称为对那些永远无法看到类型定义的代码部分不透明。

typedef struct a a_t;
a_t *var;

C 语言允许定义指向不完整类型的指针。指向不完整类型的指针本身并不是不完整的,因为指向类型的指针与 void 指针大小相同。但是,您的代码随后会尝试取消引用该指针:

var->member;

由于没有struct a可用的定义,编译器在你的程序中发现了一个错误,并告诉你它。这不是链接器问题,而是程序中的语义错误。

不透明类型是一种向该类型的用户隐藏实现细节的方法。也就是说,它是 C 提供接口的方式:

typedef struct a a_t;

a_t *a_create ();
void a_destroy (a_t *);
int a_get_member (a_t *);
void a_set_member(a_t *, int);

然后,在您的代码中,您应该使用该接口。

a_t *var = a_create();
a_set_member(var, 10);
int m = a_get_member(var);
a_destroy(var);

实现接口的源文件实际上会定义struct a外观。由于您说您在调试器中没有要引用的定义,这可能意味着您没有在程序的任何地方提供定义。

编辑:您似乎正在尝试使用数据包捕获库。您需要将<pcap.h>头文件包含到您的代码中,并使用-lpcap. 如果头文件或库不存在,您将需要为您的操作系统安装数据包捕获开发包。已经为它<pcap.h>创建了一个 typedef pcap_t,并且它是故意不透明的。所以你必须使用头文件定义的接口来访问你想要的信息。

于 2012-07-07T16:31:59.577 回答