我知道以前可能会问过这个问题,但是我想采取自己的方法,并征求意见或采取更好的方法。我有三个文件a.h a.c,main.c关于struct的函数原型,将在a.h实现中a.c并从main.c结构中调用实现,这很简单,它看起来像这样
struct ctx{
int x;
};
Run Code Online (Sandbox Code Playgroud)
我希望a.c能够操纵该结构的内容,但要防止main对其中的内容有任何了解。所以我想将struct定义放在里面,a.c而不是a.h放在struct ctx;原型中a.h
。这可以工作,但是ctx不能再分配到堆栈中,main.c因为编译器不知道要分配的大小。因此,这引出了我的第一个问题:是否有一种方法可以在不知道结构定义的情况下在堆栈中分配本地结构。
因此,我假设如果在堆栈上不可能,那么我可以将其传递到堆上,而不是通过创建一个简单的返回指针的init函数。那确实可行,但是会使流程复杂化吗?
a.h
#ifndef a_h
#define a_h
#include <stdio.h>
#include <stdlib.h>
struct ctx;
int incctx(struct ctx* c);
struct ctx* initctx(void);
void destroyctx(struct ctx* c);
#endif /* a_h */
Run Code Online (Sandbox Code Playgroud)
a.c
#include "a.h"
struct ctx{
int x;
};
int incctx(struct ctx* c){
return ++c->x;
}
struct ctx* initctx(){
struct ctx* c = malloc(sizeof(struct ctx));
c->x = 0;
return c;
}
void destroyctx(struct ctx* c){
free(c);
}
Run Code Online (Sandbox Code Playgroud)
main.c
#include "a.h"
int main(){
struct ctx* c = initctx();
printf("%d\n",incctx(c));
printf("%d\n",incctx(c));
printf("%d\n",incctx(c));
destroyctx(c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这种设计解决了一些缺点。1:如果我想使结构的一部分可见而不是整个东西怎么办?2:如果我想让结构定义可用于其他文件b.h,b.c请问是否需要重新定义结构?你们有没有更干净的设计?我知道有人说您可以只void*在结构中放置a 而不是特定类型,然后将它们标记为任意名称,但我认为这不是可行的解决方案。
对于可见性问题,您可以以类似继承的方式使用两个结构。
首先,您具有在头文件中定义的公共结构,并且您的API将处理指向以下结构的指针:
struct ctx
{
// Public data
};
Run Code Online (Sandbox Code Playgroud)
然后在源文件中创建一个私有结构,其中公共结构是第一个成员:
struct private_ctx
{
struct ctx ctx; // The public part of the structure
// Followed by private data
};
Run Code Online (Sandbox Code Playgroud)
在API内部,您使用private_ctx结构,而使用API的代码将仅使用公共ctx结构。
像这样的嵌套结构与继承的工作方式相似,该private_ctx结构是一个 ctx结构。您可以创建一个private_ctx结构并返回一个指针,该指针已适当地转换为ctx结构。
这是有关如何创建结构的示例:
struct ctx *create_struct(void)
{
// Allocate the private structure, which contains the public structure
struct private_ctx *data = = malloc(sizeof *data);
// Return the public part of the structure
return (struct ctx *) data;
}
Run Code Online (Sandbox Code Playgroud)
通过反向强制转换,使用私有数据同样容易:
void use_data(struct ctx *data)
{
struct private_ctx *private_data = (struct private_ctx *) data;
// Here the private data can be used...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
83 次 |
| 最近记录: |