如何在C中使用不透明指针?

如何在C中使用不透明指针?,c,pointers,C,Pointers,我正在在线阅读C语言的书,我不理解6.6关于结构指针的内容。我试图在初始化函数中返回一个指向双链接列表的指针,但我迷路了 .h具有指向引用双链接列表的不透明指针: .c实现具有列表结构定义: typedef struct list_s { node_t * head; node_t * tail; int count; //num nodes } list_t .c之后,我实现了初始化函数,问题是: d_link_list

我正在在线阅读C语言的书,我不理解6.6关于结构指针的内容。我试图在初始化函数中返回一个指向双链接列表的指针,但我迷路了

.h具有指向引用双链接列表的不透明指针:

.c实现具有列表结构定义:

    typedef struct list_s
    {
        node_t * head;
        node_t * tail;
        int count; //num nodes
    } list_t
.c之后,我实现了初始化函数,问题是:

d_link_list_t* Initialize(void)
{
     //Converting opaque pointer to real pointer
      d_link_list_t* list = (d_link_list_t*)malloc(sizeof(d_link_list_t*));



     // Now make concrete list_t pointer and set the members
      list_t  * rlP;//real list pointer
      rlP = (list_t*)malloc(sizeof(list_t));
      rlP->head = NULL;
     rlP->tail = NULL;
     rlP->count = 1;

     //cast opaque pointer to real list P PROBLEM HERE
     list = (d_link_list_t*)rlP;
      list->count = 0; //list IS NOT STRUCT

      return list;
}
我想返回
*d\u link\u list\t
,这是一个不透明的指针,将引用链接列表的实例。我希望实现.c中的所有函数都使用.h中这个不透明指针引用的列表。我根本不明白怎么做

我尝试将不透明指针强制转换为list\u t struct指针-希望不透明指针指向与结构指针相同的位置,但这似乎是错误的。尝试使用“->”访问count时会出现错误“尝试访问非结构或联合中的成员“count”

如何使void不透明指针引用我的列表结构?请帮帮我

您不需要
(void*)
,只需使用

typedef struct list_s list_t;
在头文件中,并在.c文件中定义结构列表。

此行错误:

d_link_list_t* list = (d_link_list_t*)malloc(sizeof(d_link_list_t*));
它分配了错误的内存量。您需要分配被指向对象的大小,而不是指针的大小

无论如何,这是个坏主意。该功能应为:

d_link_list_t Initialize(void)
{
// Now make concrete list_t pointer and set the members
    list_t  * rlP;
    rlP = malloc(sizeof(*rlP));
    rlP->head = NULL;
    rlP->tail = NULL;
    rlP->count = 1;        

    return rlP;
}
不确定你想用
list->count=0做什么
,因为
列表
有一个不透明类型,所以这是不可能的。还不清楚为什么要编写
rlP->count=1
而不是
=0


如果要使用指针语法(即
d\u link\u list\u t*
),则应从typedef行中删除
*

您的代码有一些问题。首先,d_link_list_t已经是一个空指针,因此在定义不透明指针时,请使用

d_link_list_t list; //list is a void pointer

and not

d_link_list_t* list; //list is a pointer to a void pointer.
其次,我认为这个代码

//Converting opaque pointer to real pointer
d_link_list_t* list = (d_link_list_t*)malloc(sizeof(d_link_list_t*));
应该为不透明指针分配空间,但您不需要这样做,正如我前面所说的,只需使用

d_link_list_t list; //list is a void pointer.
第三,当您将真实指针转换为不透明指针时,您还需要在函数末尾调整转换。使用

list = (d_link_list_t)rlP;
而不是

list = (d_link_list_t*)rlP;
最后,在最后,为什么要尝试通过不透明指针访问结构的内容。为什么会这样

list->count = 0; //list IS NOT STRUCT

创建不透明指针的整个想法是,用户不能直接访问结构。如果要访问该结构,请使用实指针或将不透明指针强制转换为指向该结构的指针。同样,整个想法是对函数的用户隐藏列表的内部实现。

不透明指针类似于C
文件的结构。在Microsoft C中,
文件
结构是

typedef struct _iobuf {
    void *_Placeholder;
} FILE;
请注意,实际字段都不存在,而唯一的成员是
void*
。这个指针实际上指向位于Microsoft C实现深处的一个秘密结构。假设它看起来像这样

typedef struct {
    int cnt;
    char *ptr;
    char *base;
    int flag;
    int fd;
} impfile;
操作
文件
指针的函数然后将
\u占位符
成员强制转换为
impfile
结构。例如,访问文件描述符的函数如下所示:

int getfd(FILE *fp)
{
    return ((impfile *) fp->_Placeholder)->fd;
}
Windows API通过句柄使用类似的技术,如
HWND

这种方法的优点是用户无法访问任何私有成员。这还允许API在不破坏任何现有代码的情况下进行更改,因为您知道没有人可以篡改该结构的隐私


这也可以应用于C++中,使用.< /P>作为一个优秀的文章/教程,关于不完整的数据类型、封装、数据隐藏、动态链接/后期绑定、不透明指针和面向对象的动态数据结构方法,请参见。而且。。。不要强制转换malloc的返回,这是没有必要的。编译器不知道它指向的是一个结构,而正是这个结构。请放心,它确实指向一个结构,您只需将其向后转换,编译器就会允许您访问该结构。谢谢大家David!第A.3节通用指针-void*供参考。@DavidC.Rankin嘿,你有其他pdf链接吗?“我收到一封403封禁邮件。@theufferfish嘿,我发邮件的时候可不是这样的。”。这个链接很好。所有示例代码都已打开

int getfd(FILE *fp)
{
    return ((impfile *) fp->_Placeholder)->fd;
}