简体   繁体   English

替代在头文件中为c中的“错误解引用指向不完整类型的指针”定义结构

[英]alternative to defining struct in header file for 'error dereferencing pointer to incomplete type' in c

I am aware that there are other questions about this which usually point to the standard solution of having both the struct and typedef struct declared and defined in the header file. 我知道关于此还有其他问题,它们通常指向在头文件中声明和定义structtypedef struct的标准解决方案。 However, I am looking at someone's else code which hasin the header: 但是,我正在查看标头中包含某人的其他代码:

struct A;
typedef struct A A_t;

Then the struct A is defined in *.c file together with the implementation of other functions. 然后在* .c文件中定义结构A以及其他功能的实现。 The implementation of A includes many defines, etc that are as well included in *.c not in the header. A的实现包括很多定义,等等也都包含在* .c中,而不包含在头文件中。

Then in main.c the header is included and I have declared and defined new functions making use of (null) pointers to A_t which gives error dereferencing pointer to incomplete type when trying to access to a member of the struct. 然后在main.c中包含标头,并且我声明和定义了新函数,它们使用了指向A_t的(空)指针,当尝试访问该结构的成员时,该error dereferencing pointer to incomplete typeerror dereferencing pointer to incomplete type

Is there an alternative to declare and define the struct and typedef into the header for this case? 在这种情况下,是否还有其他方法可以在标头中声明和定义struct和typedef?

EDIT: Just to clarify that the original code foresees that the user creates some functions which are then passed to the main routines. 编辑:只是为了澄清原始代码预见到用户创建了一些函数,然后将这些函数传递给主例程。 For instance the user is supposed to create a function to connect to a socket, close a socket connection, transmit and receive data. 例如,用户应该创建一个函数来连接到套接字,关闭套接字连接,发送和接收数据。 Since I need an identifier/filedescriptor for the socket I have added an int to A 's definition which is what I can't dereference. 因为我需要套接字的标识符/文件描述符,所以我在A的定义中添加了一个int ,这是我不能取消引用的。 I hope this clarifies the context. 我希望这可以澄清上下文。

You have two basic options: 您有两个基本选择:

  1. Define the structure and all its members in a header file to be included in all the .c files that use this structure. 在头文件中定义该结构及其所有成员,以包括在使用此结构的所有.c文件中。
  2. Leave the definition of the structure in a specific .c file which will also include the definitions of all the functions that access its members and those functions could be declared in a header file to be included in other .c files that need to manipulate the structure. 将结构的定义保留在特定的.c文件中,该文件还将包括访问其成员的所有函数的定义,并且可以在标头文件中声明这些函数,以将其包含在需要操纵该结构的其他.c文件中。 Of course, you will still be able to use pointers to this structure in other .c files but you will not be able to access its members. 当然,您仍然可以在其他.c文件中使用指向此结构的指针 ,但是您将无法访问其成员。 This method may be viewed as is one of C 's ways of providing sort of encapsulation or information hiding . 可以将这种方法视为C提供某种封装信息隐藏的一种方法

If someone has coded it like this and you assume that someone is a decent enough programmer, he might have done this on purpose. 如果有人用这种方式编写了代码,并且您认为某人是一个足够体面的程序员,那么他可能是故意这样做的。

In a proper C API design, you might have the need to expose a pointer to an internal data structure in order to be able to store context over function calls and expect your library user to receive that pointer from you, store it and hand it back with the next call into your library. 在适当的C API设计中,您可能需要公开一个指向内部数据结构的指针,以便能够在函数调用中存储上下文,并期望您的库用户从您那里收到该指针,进行存储并将其返回下次调用您的资料库。

In this case, the most simple answer is: You are not expected to mess with this pointer, and you are not expected to allocate one of those structures yourselves nor dereference a pointer to it. 在这种情况下,最简单的答案是:不会让您弄乱该指针,也不会希望自己分配这些结构之一,也不会取消对它的指针的引用。 X11 is a famous example of doing that. X11是一个著名的例子。

If you actually need to be able to dereference such a pointer or access structure members, you need access to the full structure definition in some header file. 如果实际上需要能够取消引用此类指针或访问结构成员,则需要访问某些头文件中的完整结构定义。 Your choice where you want to put the definition, you can have more than one (ie there is no such thing as "the" header file) header. 您选择要放置定义的位置,可以有多个(即没有“ the”头文件之类的东西)头。

Following your edit, I would propose you do it like so: 编辑之后,我建议您这样做:

Apparently, the creator of your library has taken a lot of care to not expose the structure outside his module - I would leave it like that. 显然,您的库的创建者已经非常注意不要在其模块之外公开该结构-我会这样。

You need to add an int to the structure and have done so, so you obviously have access to the .c source. 您需要向结构中添加一个int并已这样做,因此您显然可以访问.c源。 Do that, put it into the C file and leave the structure definition there. 这样做,将其放入C文件,并在其中保留结构定义。 Add a setInt(struct A*, int) and a getInt(struct A*) function that allows you to set and retrieve the int from such an opaque pointer (getter and setter functions). 添加一个setInt(struct A*, int)和一个getInt(struct A*)函数,该函数允许您从这样的不透明指针(getter和setter函数)中设置和检索int Expose those 2 functions in the header of the C file. 在C文件的标题中公开这两个函数。 This leaves the original intention of the information hiding intact but still allows you to extend the structure. 这保留了信息隐藏的初衷,但仍然允许您扩展结构。

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

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