对于健壮的C程序来说,这样做好/正确吗?
//File1 => Module1.h
static int Fun(int);
struct{
int (*pFn)(int)
}Interface;//File2 2 =>模块1.c
static int Fun(int){
//do something
}
Interface* Init(void)
{
Interface *pInterface = malloc(sizeof(Interface));
pInterface->pFn = Fun;
return pInterface;
}
//File 3 => Module2.c
#include"Module1.h"
main()
{
Interface *pInterface1 = Init();
pInterface1->pFn(5);
}我的目的是让每个模块暴露一个接口..。
问题:
发布于 2013-10-11 05:34:18
对于动态加载的模块来说,这更符合惯例。(或者其他类似的东西。)
通常,两个源文件之间的接口是使用直接访问的extern函数和对象定义的。你需要为做任何更复杂的事情找个理由。
发布于 2013-10-11 05:53:38
Interface对用户隐藏一级ADT模式结构的内容。或者你可以结合上面的模式。发布于 2013-10-11 06:02:42
我的简短回答是不。
忽略那些指出不应该在.h文件中声明静态函数的注释(这是您想要隐藏的部分--毕竟它是静态的),这里有一些需要记住的事情。
似乎您正在尝试使用该接口,以便将实现从模块的使用者中分离出来;这是一个崇高的目标。这可以允许增加灵活性,因为实现可以在不中断调用代码的情况下更改.c文件。但是,考虑一下您定义的接口。
使用该模块的任何代码都应该能够通过Init获得接口实例(尽管这需要包含在.h文件中)。该接口实例将指向要使用的函数。其中一个函数具有签名。
int Fun(int);那你藏了什么?当然,您可以更改他们正在调用的函数,但是您仍然必须提供一个带有该签名的函数。
或者,您只需将.h定义为:
int Fun(int);然后在.c文件中,如下所示:
static int StaticFun(int i)
{
// something
}
int Fun(int i)
{
StaticFun(i);
}您可以根据它管理的内部状态或配置文件进行有趣的调用,不管您想要什么。为什么这样更好?除了简单之外,它还是一个静态调用;例如,编译器可以内联对StaticFun的调用,甚至是函数StaticFun。通过函数指针进行调用通常会对性能造成明显的影响。
现在,可能存在"Interface“对象的情况,如您所定义的那样。但我倾向于建议,在你的情况下没有一个,不是未经修改。
假设您的Init函数更改为:
Interface* Init(some state info);现在,您返回的Interface对象可以根据传入的状态或配置进行更改,这允许模块动态映射函数。基本上,我的观点是,如果您实际上是在调用下面的静态函数,那么您的工作比需要的要努力得多,并阻止编译器优化。
请注意,如果您要走接口路线(我现在正在做一个类似的项目),那么我可以建议修改吗?就像..。
.h文件:
const Interface* Init(some state);.c文件:
static int FunTyp1(int);
static int FunTyp2(int);
static const Interface typ1 = { &FunTyp1 };
static const Interface typ2 = { &FunTyp2 };
const Interface* Init(some state)
{
if (some state == type1)
return &typ1;
else if (some state == type2)
return &typ2;
}优势:
注意,通过具有多个静态初始化实例,您可以为要支持的每个函数映射定义一个不同的"Interface“对象。
https://stackoverflow.com/questions/19291647
复制相似问题