<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />这次翻译感觉很差,如果您有更好的翻译请寄一份我,谢谢!jiangray@126.com。希望大家互相交流,互相学习。
9.1.5 Fallback回退、回滚 Function Implementations <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
Due to the huge number of Unix varieties in common use today, many of the C library functions that you take for granted on your preferred development platform are very likely missing from some of the architectures you would like your code to compile on. Fundamentally there are two ways to cope with this:
Use only the few library calls that are available everywhere. In reality this is not actually possible because there are two lowest common denominators最小共同点 with mutually exclusive互斥的 APIs, one rooted in BSD Unix (`bcopy', `rindex') and the other in SYSV Unix (`memcpy', `strrchr'). The only way to deal with this is to define one API in terms of the other using the preprocessor. The newer POSIX standard deprecates反对 many of the BSD originated calls (with exceptions such as the BSD socket API). Even on non-POSIX platforms, there has been so much cross pollination that often both varieties of a given call may be provided, however you would be wise to write your code using POSIX endorsed calls, and where they are missing, define them in terms of whatever the host platform provides.
This approach requires a lot of knowledge about various system libraries and standards documents, and can leave you with reams of大量 preprocessor code to handle the differences between APIS. You will also need to perform a lot of checking in `configure.in' to figure out which calls are available. For example, to allow the rest of your code to use the `strcpy' call with impunity, you would need the following code in `configure.in':
AC_CHECK_FUNCS(strcpy bcopy)
And the following preprocessor code in a header file that is seen by every source file:
#if !HAVE_STRCPY
# if HAVE_BCOPY
# define strcpy(dest, src) bcopy (src, dest, 1 + strlen (src))
# else /* !HAVE_BCOPY */
error no strcpy or bcopy
# endif /* HAVE_BCOPY */
#endif /* HAVE_STRCPY */
Alternatively you could provide your own fallback implementations of function calls you know are missing on some platforms. In practice you don't need to be as knowledgeable博学的 about problematic有问题的 functions when using this approach. You can look in GNU libiberty(9) or Fran?ois Pinard's libit project(10) to see for which functions other GNU developers have needed to implement fallback code. The libit project is especially useful in this respect as it comprises由、、组成 canonical标准的 versions of fallback functions, and suitable Autoconf macros assembled from across the entire GNU project. I won't give an example of setting up your package to use this approach, since that is how I have chosen to structure the project described in this chapter.
Rather than writing code to the lowest common denominator of system libraries, I am a strong advocate拥护 of the latter school of thought思想派别 in the majority 占大多数of cases. As with all things it pays to take a pragmatic实用的 approach; don't be afraid of the middle ground -- weigh the options on a case by case basis.
由于目前有很多Unix版本正在使用之中,很多C库函数你认为在你选择的开发平台中是理所当然的事,然而很有可能在你编译代码的平台上就有可能没有这些库函数。有两个基本的方法用来处理这种情况:
尽可能在任何位置尽可能少的使用函数库调用。实际上,这种方法实用性不大,因为存在两组共同点小缺互相互斥的API,一组基于BSD Unix(’bcopy’ ’rindex’),而另一组基于SYSV Unix(‘memcpy’‘strrchr’)。处理这个问题唯一的的方法就是根据其它的预处理器定义一个API。最新的POSIX标准不支持BSD原始的系统调用(BSD socket API除外)。甚至在非POSIX平台,存在如此多的cross pollination以至于所有的平台都可能提供一种系统调用的版本,所以你写的代码最好使用POSIX认可的系统调用,并且当这些系统调用不存在时,就自己定义这些系统调用。
这种方法需要了解各种系统函数库和有关各种标准的文档,并且这会使你需要大量的预处理代码来处理各种API之间的差异。你将来也需要在configure.in文件中做很多检测来确定哪些系统调用是可用的。举例来说,为了在后续代码中安全的使用‘strcpy’系统调用,在configure.in文件中需要添加如下代码:AC_CHECK_FUNCS(strcpy bcopy)
并且在所有的源文件可以看到下面的预处理代码出现在头文件中:
#if !HAVE_STRCPY
# if HAVE_BCOPY
# define strcpy(dest, src) bcopy (src, dest, 1 + strlen (src))
# else /* !HAVE_BCOPY */
error no strcpy or bcopy
# endif /* HAVE_BCOPY */
#endif /* HAVE_STRCPY */
另外一个方法就是当你知道在某些平台没有某些函数调用时,你自己实现关于函数调用的后退功能。实际上当你使用该方法时,你不需要详细了解那些有问题的函数。你可以查看GNU libiberty 或者Francois Pinard‘s libit项目来看看哪个函数其它的GNU开发人员已经实现它的后退代码。由于libit项目由许多后退函数的标准版本组成,所以这个项目在这方面特别有效,并且合适的autoconf宏组合在整个GNU项目中。这里我不会给出在代码包中使用该方法的实例,因为这些在本章给出的项目中有相关的描述。
与其根据各系统函数库的最小共同点来写代码,不如使用后一种大家都使用的方法。对于所有的事情来说还是采用实用的的方法,就是具体情况具体分析。
文章评论(0条评论)
登录后参与讨论