日期:2014-05-16  浏览次数:20749 次

问一个关于引用外部函数的问题.用了三种方法,其中是不是有多余的?50分求助
A.h/c   B.h/c。现在A要引用B的一个函数X。我现在为此做了3件事:
1.将X在B.h中声明,然后在A.h中include   B.h
2.在A.h中直接写上   extern   X
3.在Makefile中,A.o:B.o(即形成A.o需要B.o)

现在想问是否这三件事都需要做,还是有些重复了。一般是怎样引用一个外部函数.
还有就是一般.h文件中是否声明的都是可能被外部子程序引用的函数,还是凡是在.c文件中出现的函数都必须在.h中进行声明?
谢谢!50分求助


------解决方案--------------------
简单的方法是看标准源码
以下是从FreeBSD 5.4 的源码中摘出来的
/usr/include/string.h
...
char *strcpy(char * __restrict, const char * __restrict);
...

/usr/src/lib/libc/string/strcpy.c
...
#include <string.h>

char *
strcpy(char * __restrict to, const char * __restrict from)
{
char *save = to;

for (; (*to = *from); ++from, ++to);
return(save);
}
...

在用户程序中如果需要调用strcpy函数
标准的方法是
#include <string.h>
从摘string.h摘一行
char *strcpy(char * __restrict, const char * __restrict)
也是可以的

至于extern关键子,对函数来说,可以省略,全局变量必须使用。

现在回答楼主的问题:
1或者2任选一件,推荐使用1,不过如果X函数只在A中使用,建议在a.c中include b.h
3. 是不必要的,链接时链接上b.o就可以了。

------解决方案--------------------
楼上正解.

一般接口就是这样写的.不过:
将X在B.h中声明,这是对的,
然后在A.h中include B.h------一般是A.c中include B.h.因为A.h做为A.c的对外接口,不应该有其
他接口的内容.若不然,在一些复杂的系统中,编译会出问题.特别是出现交叉include时比如:a.c要调用b.c
内的一个函数,而b.c又要调用a.c内的函数就会出现a.h内include b.h,b.h内include a.h,有些编译器
就会出问题.当然这种问题是编程方法不好所引起的,但我们要预防这些这中情况的发生.



------解决方案--------------------
1是完全可以的.
2也是完全可以的.
3个人感觉是不可以的, 因为是编译器依赖, 与链接没有关系. 而且这样会造成makefile很难看, 修改起来很麻烦.
------解决方案--------------------
楼上已经回答得很充分了
补充一下3:
Makefile中a.o: b.o的意思是
如果b.o有改变,那么a.o需要重新编译
但实际上是:a.o只是调用了b.o中的函数,只要接口不变,即使函数内容变了,a.o都不需要重新编译。
所以应该写成:
a.o: a.c a.h b.h
(这3个变了才应该导致a.o重新编译)
但程序与a.o和b.o有关
bin: a.o b.o