【发布时间】:2021-02-26 14:39:26
【问题描述】:
我正在尝试设置一个系统,在该系统中我传递一个指向结构的指针,同时向最终用户隐藏结构的定义。我有两个似乎可行的选择,但我不知道我是否让这变得比需要的更难,错过权衡,或者只是做一些非常愚蠢的事情。对于任何方法,我都坚持使用 C,不能使用 C++。此外,这最终将需要与 Fortran 程序进行对话,我正在努力使其尽可能简单。
我有一个小工具来演示这个概念。选项一使用指向指针的 void 指针,以便我可以在必要时从函数返回一个状态整数。但是,我不喜欢在通话之前进行 malloc,因为我担心 Fortran 方面的事情。这可能是没有根据的,因为我还没有做过那个演示。选项二只是从函数返回一个 void 指针,但我失去了以这种方式返回状态的能力。对于这两个版本,我确实有一个自定义的免费功能,即使不一定使用确切的当前实现。该结构有它自己的 void 指针,它将根据选项输入进行定义,并且作为拆卸过程的一部分,它需要释放它。
#include <stdio.h>
#include <stdlib.h>
struct State
{
int type;
void *data;
};
int Init1(int option, void **state);
void* Init2(int option);
void printState(void *state);
void free1(void **state);
void free2(void *state);
void* allocateData(int option);
int main(int argc, char *argv[])
{
void **ps1;
void *s2;
int ret;
ps1 = malloc(sizeof(void*));
ret = Init1(1, ps1);
printState(*ps1);
free1(ps1);
s2 = Init2(2);
printState(s2);
free2(s2);
return 0;
}
int Init1(int option, void **state)
{
(*state) = malloc(sizeof(struct State));
struct State* ret = *state;
ret->type = option;
return 0;
}
void free1(void **state)
{
free(*state);
free(state);
}
void* Init2(int option)
{
struct State* ret = malloc(sizeof(struct State));
ret->type = option;
return ret;
}
void free2(void *state)
{
free(state);
}
void printState(void *state)
{
struct State* data = state;
printf("Type : %d\n", data->type);
}
【问题讨论】:
-
不需要
void *。用户可以在不知道结构成员的情况下声明struct State *s。 -
同意@WilliamPursell - 检查“不透明结构”。
-
另外,不需要初始 malloc。你可以做
void *ps1; Init1(1, &ps1); -
如果你使用 void 指针,你会失去很多 C 提供的类型安全性。不要设计带有 void 指针的接口。使用不透明类型或指向不透明类型的指针。示例见标准 I/O 库和 FILE 指针类型
-
通过对不透明指针的快速阅读,看起来它在与 Fortran 接口时会增加一定程度的复杂性,尽管仍然可能。感谢您提供有关初始 malloc 的提示。