关于如何让jre显示中文字体的方法

创建:2005-10-28 00:09:13
作者:Unlinux
来自: http://www.Unlinux.com

由于jre里font.properies默认的字体是 Turbolinux里的-tlc-song-字体,如果你没有这种字体,肯定显示的都是“口”,解决方法有2种,一个就是按照jre里的说明,按照它的方法自己添加字体,但是这个难度比较大,需要用它提供的脚本,但是对于我们这些不是很了解java程序的菜鸟来说,这个方法显然有点难度。于是,我就想,既然我自己没有办法生成字体目录,我就改我原来的fonts.dir,让它支持这种-tlc-song-字体,同时保持原来的字体-misc- simsun-。更改的方法有很多种,我的方法不一定最好,也不一定是最简单,如果那个兄弟有更好的方法,可以写出来。
1> 新生成一个fonts.dir;
2> 在原来的fonts.dir里增加新的字体定义。
我以前一种为例子,具体方法如下:
1.在/usr/X11R6/lib/X11/fonts/trutype/下建立一个新的目录ttf-zh(目录名随便你起),然后将simsun.ttf,tahoma字体拷贝至这个新建立的目录。
2.将simsun.ttf改名为tlc_song.ttf,将tahoma.ttf改为tlc_song_ascii.ttf。
3.生成fonts.dir文件:
132
tlc_song_ascii.ttf -tlc-song-medium-r-normal–0-0-0-0-p-0-iso8859-1
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-iso10646-1
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-gbk-0
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-gb2312.1980-0
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-gb18030.2000-1
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-gb18030.2000-0
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-gb18030-0
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-big5.eten-0
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-big5.et-0
tlc_song.ttf -tlc-song-medium-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:tlc_song_ascii.ttf -tlc-song-medium-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-iso10646-1
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-gbk-0
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-gb2312.1980-0
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-gb18030.2000-1
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-gb18030.2000-0
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-gb18030-0
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-big5.eten-0
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-big5.et-0
ai=0.3:tlc_song.ttf -tlc-song-medium-i-normal–0-0-0-0-c-0-big5-0
ds=y:tlc_song_ascii.ttf -tlc-song-bold-r-normal–0-0-0-0-p-0-iso8859-1
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-iso10646-1
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-gbk-0
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-gb2312.1980-0
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-gb18030.2000-1
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-gb18030.2000-0
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-gb18030-0
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-big5.eten-0
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-big5.et-0
ds=y:tlc_song.ttf -tlc-song-bold-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:ds=y:tlc_song_ascii.ttf -tlc-song-bold-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-iso10646-1
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-gbk-0
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-gb2312.1980-0
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-gb18030.2000-1
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-gb18030.2000-0
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-gb18030-0
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-big5.eten-0
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-big5.et-0
ai=0.3:ds=y:tlc_song.ttf -tlc-song-bold-i-normal–0-0-0-0-c-0-big5-0
tlc_song_ascii.ttf -tlc-ming-medium-r-normal–0-0-0-0-p-0-iso8859-1
tlc_song.ttf -tlc-ming-medium-r-normal–0-0-0-0-c-0-big5.eten-0
tlc_song.ttf -tlc-ming-medium-r-normal–0-0-0-0-c-0-big5.et-0
tlc_song.ttf -tlc-ming-medium-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:tlc_song_ascii.ttf -tlc-ming-medium-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:tlc_song.ttf -tlc-ming-medium-i-normal–0-0-0-0-c-0-big5.eten-0
ai=0.3:tlc_song.ttf -tlc-ming-medium-i-normal–0-0-0-0-c-0-big5.et-0
ai=0.3:tlc_song.ttf -tlc-ming-medium-i-normal–0-0-0-0-c-0-big5-0
ds=y:tlc_song_ascii.ttf -tlc-ming-bold-r-normal–0-0-0-0-p-0-iso8859-1
ds=y:tlc_song.ttf -tlc-ming-bold-r-normal–0-0-0-0-c-0-big5.eten-0
ds=y:tlc_song.ttf -tlc-ming-bold-r-normal–0-0-0-0-c-0-big5.et-0
ds=y:tlc_song.ttf -tlc-ming-bold-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:ds=y:tlc_song_ascii.ttf -tlc-ming-bold-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:ds=y:tlc_song.ttf -tlc-ming-bold-i-normal–0-0-0-0-c-0-big5.eten-0
ai=0.3:ds=y:tlc_song.ttf -tlc-ming-bold-i-normal–0-0-0-0-c-0-big5.et-0
ai=0.3:ds=y:tlc_song.ttf -tlc-ming-bold-i-normal–0-0-0-0-c-0-big5-0
tlc_song.ttf -tlc-mincho-medium-r-normal–0-0-0-0-c-0-jisx0212.1990-0
tlc_song.ttf -tlc-mincho-medium-r-normal–0-0-0-0-c-0-jisx0208.1990-0
tlc_song.ttf -tlc-mincho-medium-r-normal–0-0-0-0-c-0-jisx0208.1983-0
tlc_song.ttf -tlc-mincho-medium-r-normal–0-0-0-0-c-0-jisx0201.1976-0
tlc_song_ascii.ttf -tlc-mincho-medium-r-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:tlc_song.ttf -tlc-mincho-medium-i-normal–0-0-0-0-c-0-jisx0212.1990-0
ai=0.3:tlc_song.ttf -tlc-mincho-medium-i-normal–0-0-0-0-c-0-jisx0208.1990-0
ai=0.3:tlc_song.ttf -tlc-mincho-medium-i-normal–0-0-0-0-c-0-jisx0208.1983-0
ai=0.3:tlc_song.ttf -tlc-mincho-medium-i-normal–0-0-0-0-c-0-jisx0201.1976-0
ai=0.3:tlc_song_ascii.ttf -tlc-mincho-medium-i-normal–0-0-0-0-p-0-iso8859-1
ds=y:tlc_song.ttf -tlc-mincho-bold-r-normal–0-0-0-0-c-0-jisx0212.1990-0
ds=y:tlc_song.ttf -tlc-mincho-bold-r-normal–0-0-0-0-c-0-jisx0208.1990-0
ds=y:tlc_song.ttf -tlc-mincho-bold-r-normal–0-0-0-0-c-0-jisx0208.1983-0
ds=y:tlc_song.ttf -tlc-mincho-bold-r-normal–0-0-0-0-c-0-jisx0201.1976-0
ds=y:tlc_song_ascii.ttf -tlc-mincho-bold-r-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:ds=y:tlc_song.ttf -tlc-mincho-bold-i-normal–0-0-0-0-c-0-jisx0212.1990-0
ai=0.3:ds=y:tlc_song.ttf -tlc-mincho-bold-i-normal–0-0-0-0-c-0-jisx0208.1990-0
ai=0.3:ds=y:tlc_song.ttf -tlc-mincho-bold-i-normal–0-0-0-0-c-0-jisx0208.1983-0
ai=0.3:ds=y:tlc_song.ttf -tlc-mincho-bold-i-normal–0-0-0-0-c-0-jisx0201.1976-0
ai=0.3:ds=y:tlc_song_ascii.ttf -tlc-mincho-bold-i-normal–0-0-0-0-p-0-iso8859-1
tlc_song_ascii.ttf -tlc-HanyiSong-medium-r-normal–0-0-0-0-p-0-iso8859-1
tlc_song.ttf -tlc-HanyiSong-medium-r-normal–0-0-0-0-c-0-iso10646-1
tlc_song.ttf -tlc-HanyiSong-medium-r-normal–0-0-0-0-c-0-gbk-0
tlc_song.ttf -tlc-HanyiSong-medium-r-normal–0-0-0-0-c-0-gb2312.1980-0
tlc_song.ttf -tlc-HanyiSong-medium-r-normal–0-0-0-0-c-0-gb18030-0
tlc_song.ttf -tlc-HanyiSong-medium-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:tlc_song_ascii.ttf -tlc-HanyiSong-medium-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:tlc_song.ttf -tlc-HanyiSong-medium-i-normal–0-0-0-0-c-0-iso10646-1
ai=0.3:tlc_song.ttf -tlc-HanyiSong-medium-i-normal–0-0-0-0-c-0-gbk-0
ai=0.3:tlc_song.ttf -tlc-HanyiSong-medium-i-normal–0-0-0-0-c-0-gb2312.1980-0
ai=0.3:tlc_song.ttf -tlc-HanyiSong-medium-i-normal–0-0-0-0-c-0-gb18030-0
ai=0.3:tlc_song.ttf -tlc-HanyiSong-medium-i-normal–0-0-0-0-c-0-big5-0
ds=y:tlc_song_ascii.ttf -tlc-HanyiSong-bold-r-normal–0-0-0-0-p-0-iso8859-1
ds=y:tlc_song.ttf -tlc-HanyiSong-bold-r-normal–0-0-0-0-c-0-iso10646-1
ds=y:tlc_song.ttf -tlc-HanyiSong-bold-r-normal–0-0-0-0-c-0-gbk-0
ds=y:tlc_song.ttf -tlc-HanyiSong-bold-r-normal–0-0-0-0-c-0-gb2312.1980-0
ds=y:tlc_song.ttf -tlc-HanyiSong-bold-r-normal–0-0-0-0-c-0-gb18030-0
ds=y:tlc_song.ttf -tlc-HanyiSong-bold-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:ds=y:tlc_song_ascii.ttf -tlc-HanyiSong-bold-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:ds=y:tlc_song.ttf -tlc-HanyiSong-bold-i-normal–0-0-0-0-c-0-iso10646-1
ai=0.3:ds=y:tlc_song.ttf -tlc-HanyiSong-bold-i-normal–0-0-0-0-c-0-gbk-0
ai=0.3:ds=y:tlc_song.ttf -tlc-HanyiSong-bold-i-normal–0-0-0-0-c-0-gb2312.1980-0
ai=0.3:ds=y:tlc_song.ttf -tlc-HanyiSong-bold-i-normal–0-0-0-0-c-0-gb18030-0
ai=0.3:ds=y:tlc_song.ttf -tlc-HanyiSong-bold-i-normal–0-0-0-0-c-0-big5-0
tlc_song_ascii.ttf -tlc-default-medium-r-normal–0-0-0-0-p-0-iso8859-1
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-iso10646-1
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-gbk-0
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-gb2312.1980-0
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-gb18030-0
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-big5.eten-0
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-big5.et-0
tlc_song.ttf -tlc-default-medium-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:tlc_song_ascii.ttf -tlc-default-medium-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-iso10646-1
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-gbk-0
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-gb2312.1980-0
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-gb18030-0
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-big5.eten-0
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-big5.et-0
ai=0.3:tlc_song.ttf -tlc-default-medium-i-normal–0-0-0-0-c-0-big5-0
ds=y:tlc_song_ascii.ttf -tlc-default-bold-r-normal–0-0-0-0-p-0-iso8859-1
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-iso10646-1
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-gbk-0
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-gb2312.1980-0
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-gb18030-0
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-big5.eten-0
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-big5.et-0
ds=y:tlc_song.ttf -tlc-default-bold-r-normal–0-0-0-0-c-0-big5-0
ai=0.3:ds=y:tlc_song_ascii.ttf -tlc-default-bold-i-normal–0-0-0-0-p-0-iso8859-1
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-iso10646-1
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-gbk-0
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-gb2312.1980-0
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-gb18030-0
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-big5.eten-0
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-big5.et-0
ai=0.3:ds=y:tlc_song.ttf -tlc-default-bold-i-normal–0-0-0-0-c-0-big5-0
生成fonts.scale:cp fonts.dir fonts.scale。
4.修改/etc/X11/XF86config文件,增加字体目录FontPath "/usr/X11R6/lib/X11/fonts/truetype/ttf-zh"
5.运行SuSEconfig,如果没有什么错误提示,重新启动xwindow,你此时运行/jre/bin/ControlPanel就会见到下面的图样。

注意事项:如果你新安装了jre1.4.1_01的话,建议安装到原来系统的默认目录/usr/lib/SunJava2-1.3.1中。同时修改. /jre/lib/font.properties.zh.Turbo,将其改名为font.properties.zh。否则仍然是“口”。
至此,一切就搞定了。

尝试:如果不想新建立目录和fonts.dir,可以在原来的fonts.dir中增加上面的字体脚本,但是要将开头的数字改为x+132(这个是说明下面有多少行,必需改)。然后做2个联接,ln -s simsun.ttf tlc_song.ttf,ln -s tahoma.ttf tlc_song_ascii.ttf。然后运行SuSEconfig,重新启动xwindow。这种改动最小,只是我当时怕这样该引起原来的字体混乱,所以按照前述的方法修改。如有不对之处,还请大家指教。
转载自:http://www.unlinux.com/doc/java/20051028/5830.html

[转]往JRE里添加新字体

   Adding Fonts to the Java Runtime
要加一种亚洲字体进JRE,请按以下步骤进行:
1.装入字体
首先,你必须装载中文、日文、韩文或传统的中文字体(楷书、宋体等)到你的系统里面
2.复制字体进font.properties
装好了字体后,复制你感兴趣字体的descriptio到font.properties,最简捷的方法是把
font.properties.<locale>直接改名为font.properties

例如:要使用中文字体,你可以复制或者改名font.properties.zh为font.properties.
现行的WIN32 JDK提供如下font properties 文件
./lib/font.properties
./lib/font.properties.ja
./lib/font.properties.ko
./lib/font.properties.zh
./lib/font.properties.zh_TW
     
并且你可以在JRE里使用多于一种的亚洲字体,所必须做的就是编辑font.properties
文件。
例如你要加三种SERIF字体;
serif.0=Times New Roman,ANSI_CHARSET
serif.1=WingDings,SYMBOL_CHARSET,NEED_CONVERTED
serif.2=Symbol,SYMBOL_CHARSET,NEED_CONVERTED
<virtual font name>.<index number> = <platform font name>, attributes

后面有三个参数,如Times New Roman、WingDings就是字体名
第二个参数(SYMBOL_CHARSET)是相应字符集的处理接口
第三个参数是表明相应字符集不能直接同过UNICODE编码处理,需要与UNICODE间的转换器
通过以下语句设不同FONTS的转换器
fontcharset.serif.1=sun.awt.windows.CharToByteWingDings
fontcharset.serif.2=sun.awt.CharToByteSymbol

用户也可以定制自己的字体、字符集与自定义的UNICODE转换器

例如说你想增加你自己定制的字体到JAVA的serif     系列字体里去,
假设你的字体共有256个,从0到0Xff.正对应于UNICODE里的OXE000-0XEOFF。
首先你要设计你的转换类
package mypkg.converter;

import sun.io.CharToByteISO8859_1;
import sun.io.CharToByteConverter;
import sun.io.ConversionBufferFullException;

public class CharToByteMyFont extends sun.io.CharToByteISO8859_1 {

    /*
     * This method indicates the range this font covers.
     */
    public boolean canConvert(char ch) {
       if (ch >= 0xe000 && ch <= 0xe0ff) {
          return true;
       }
       return false;
    }

    /*
     * This method converts the unicode to this font index.
     */
    public int convert(char[] input, int inStart, int inEnd,
                       byte[] output, int outStart, int outEnd)
                       throws ConversionBufferFullException {
       int outIndex = outStart;
       for (int i = inStart; i < inEnd; i++) {
          char ch = input[i];
          if (ch >= 0xe000 && ch <= 0xe0ff) {
             if (outIndex >= outEnd)
             throw new ConversionBufferFullException();
             output[outIndex++] = (byte)(ch – 0xe000);
          }
       }
       return outIndex – outStart;
    }
第二步,加你自己的字体和转换器进Properties文件
你先要增加你的字体的名子进文件里,
如
serif.3=<your own font name>
然后定义相应的converter
fontcharset.serif.3=mypkg.converter.CharToByteMyfont

为了确定JRE能够找到你的转换器,你的application classpath 必须包含转换器的路径

以上是我看了sun里的相关文章后觉得很不错而粗略整理出来的,目的只在于把相关内容大概介绍一下,请不要见笑,最好参考英文原文
http://java.sun.com/products/jdk/1.1/docs/guide/intl/fontprop.html
或到http://java.sun.com/products/jdk/1.1/docs/guide/intl/index.html看更多的Internationalization相关资料以及samples
本人正在做多国语的网版词典,所以有在找相关资料,这是我看到的比较有用的叙述JAVA中字符集处理的文章,如果各位看到更好的java对unicode支持的资料请告知我,谢谢

解析C语言复杂声明

C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法。不过,右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的,两者可以说是相反的。右左法则的英文原文是这样说的:

The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed.

这段英文的翻译如下:

右左法则:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。

笔者要对这个法则进行一个小小的修正,应该是从未定义的标识符开始阅读,而不是从括号读起,之所以是未定义的标识符,是因为一个声明里面可能有多个标识符,但未定义的标识符只会有一个。

现在通过一些例子来讨论右左法则的应用,先从最简单的开始,逐步加深:

int (*func)(int *p);

首先找到那个未定义的标识符,就是func,它的外面有一对圆括号,而且左边是一个*号,这说明func是一个指针,然后跳出这个圆括号,先看右边,也是一个圆括号,这说明(*func)是一个函数,而func是一个指向这类函数的指针,就是一个函数指针,这类函数具有int*类型的形参,返回值类型是 int。

int (*func)(int *p, int (*f)(int*));

func被一对括号包含,且左边有一个*号,说明func是一个指针,跳出括号,右边也有个括号,那么func是一个指向函数的指针,这类函数具有int *和int (*)(int*)这样的形参,返回值为int类型。再来看一看func的形参int (*f)(int*),类似前面的解释,f也是一个函数指针,指向的函数具有int*类型的形参,返回值为int。

int (*func[5])(int *p);

func 右边是一个[]运算符,说明func是一个具有5个元素的数组,func的左边有一个*,说明func的元素是指针,要注意这里的*不是修饰func的,而是修饰func[5]的,原因是[]运算符优先级比*高,func先跟[]结合,因此*修饰的是func[5]。跳出这个括号,看右边,也是一对圆括号,说明func数组的元素是函数类型的指针,它所指向的函数具有int*类型的形参,返回值类型为int。

int (*(*func)[5])(int *p);

func 被一个圆括号包含,左边又有一个*,那么func是一个指针,跳出括号,右边是一个[]运算符号,说明func是一个指向数组的指针,现在往左看,左边有一个*号,说明这个数组的元素是指针,再跳出括号,右边又有一个括号,说明这个数组的元素是指向函数的指针。总结一下,就是:func是一个指向数组的指针,这个数组的元素是函数指针,这些指针指向具有int*形参,返回值为int类型的函数。

int (*(*func)(int *p))[5];

func是一个函数指针,这类函数具有int*类型的形参,返回值是指向数组的指针,所指向的数组的元素是具有5个int元素的数组。

要注意有些复杂指针声明是非法的,例如:

int func(void) [5];

func是一个返回值为具有5个int元素的数组的函数。但C语言的函数返回值不能为数组,这是因为如果允许函数返回值为数组,那么接收这个数组的内容的东西,也必须是一个数组,但C语言的数组名是一个右值,它不能作为左值来接收另一个数组,因此函数返回值不能为数组。

int func[5](void);

func是一个具有5个元素的数组,这个数组的元素都是函数。这也是非法的,因为数组的元素除了类型必须一样外,每个元素所占用的内存空间也必须相同,显然函数是无法达到这个要求的,即使函数的类型一样,但函数所占用的空间通常是不相同的。

作为练习,下面列几个复杂指针声明给读者自己来解析,答案放在第十章里。

int (*(*func)[5][6])[7][8];

int (*(*(*func)(int *))[5])(int *);

int (*(*func[7][8][9])(int*))[5];

实际当中,需要声明一个复杂指针时,如果把整个声明写成上面所示的形式,对程序可读性是一大损害。应该用typedef来对声明逐层分解,增强可读性,例如对于声明:

int (*(*func)(int *p))[5];

可以这样分解:

typedef int (*PARA)[5];
typedef PARA (*func)(int *);

这样就容易看得多了。

Linux下配置功能完善的web服务器

调试环境:Redhat9.0 Apache1.3.29 Mysql3.23.58 PHP4.3.4

Linux系统的安装我就不讲了,这是基本功,其实这篇文章在类似Redhat的其他linux也应该通用,大家只要掌握我提供的方法就行。记 得安装Redhat9。0的时候不要安装系统默认的apache,mysql和php以及相关的软件。已经安装的请用rpm -e * 删除已经安装的包。

1.安装Mysql3.23.58

其实老实说直接安装Mysql官方网站提供的rpm包也是一个比较可行的办法,他的官方网站的rpm包的提供基本跟tar包发行是同步的,这点 我比较喜欢,至少安装rpm包的在后面的调试中不会出现mysql库文件找不到的情况。但这里还是有必要讲一下自定义安装的步骤,毕竟网友自定义安装的还 说挺多的。

软件获取:http://www.mysql.com/downloads/index.html

安装步骤:

tar zxvf mysql-3.23.58.tar.gz

cd mysql-3.23.58

./configure –prefix=/usr/local/mysql –sysconfdir=/etc –localstatedir=/var/lib/mysql

make

make install

#prefix=/usr/local/mysql mysql安装的目标目录

#sysconfdir=/etc my.ini配置文件的路径

#localstatedir=/var/lib/mysql 数据库存放的路径

安装完以后要初始化数据库,当然你是升级的话不用做这步;

/usr/local/mysql/bin/mysql_install_db

如果系统没有mysql这个用户的话,最好做以下这步:

useradd -M -o -r -d /var/lib/mysql -s /bin/bash -c "MySQL Server" -u 27 mysql

然后我启动mysql

/usr/local/mysql/bin/safe_mysqld &

ok,先看看mysql能否正常工作

mysql -uroot mysql

一般情况下都是不能正常链接数据库,错误提示一般为:

ERROR 2002: Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’ (2)

其实网上大家问的最多的都是整个问题,说什么链接不到mysqld.sock,其实大家不妨看看mysql的错误日志就明白怎么回事,我这里的错误日志是在

/var/lib/mysql/*.err 你会发现mysql只所以不能启动,是因为/var/lib/mysql的权限不允许mysql服务访问,英文mysql默认是调用mysql用户来启动服务的,好了,既然知道是什么原因找到不能启动,那就简单了。我们只要

chown -R mysql:mysql /var/lib/mysql 就行,如果还是启动不了,再慢慢调试权限,反正一般启动不了都是权限的问题。

如果大家还是不能启动不了的话,那就用我的比较繁琐的权限的设置,反正我每次都是这么做的,一般不会有问题,见下:

chown -R root /usr/local/mysql

chgrp -R mysql /usr/local/mysql

chown -R root /usr/local/mysql/bin

chgrp -R mysql /usr/local/mysql/bin

chgrp -R mysql /var/lib/mysql

chmod 777 /var/lib/mysql

chown -R root /var/lib/mysql/mysql

chgrp -R mysql /var/lib/mysql/mysql

chmod 777 /var/lib/mysql/mysql

chown -R root /var/lib/mysql/mysql/*

chgrp -R mysql /var/lib/mysql/mysql/*

chmod 777 /var/lib/mysql/mysql/*

chmod 777 /usr/local/mysql/lib/mysql/libmysqlclient.a

做完上面的步骤,然后把你编译目录的一个脚本COPY过去

cp support-files/mysql.server /etc/rc.d/init.d/mysqld

chkconfig –add mysqld

用ntsysv设置使mysql每次启动都能自动运行。

好了,至此mysql安装完毕,你可以这样起动你的mysql服务

/etc/rc.d/init.d/mysqld start

下面这步比较关键,

ln -s /usr/local/mysql/lib/mysql /usr/lib/mysql

ln -s /usr/local/mysql/include/mysql /usr/include/mysql

大家可以不做这步,大可以在编译其他软件的时候自定义myslq的库文件路径,但我还是喜欢把库文件链接到默认的位置,这样你在编译类似PHP,Vpopmail等软件时可以不用指定mysql的库文件地址。

2.安装Apache1.3.29

我没有选择安装Apache2.0是我对他还是不放心,因为网上最新公布的apache的漏洞基本上是针对2.0,当然大家可以自己选择安装相应的版本。我这里讲的都是采用DSO动态编译的方法编译Apache.

至于有关apache的编译方法,可以参考我以前的文章《apache的静态/动态编译在apache+php+mysql的应用》 http://www.5ilinux.com/apache01.html

软件获取:http://httpd.apache.org/

tar zvxf apache_1.3.29.tar.gz

cd apache_1.3.29

修改src/include/httpd.h 增大最大线程数

#define HARD_SERVER_LIMIT 256

改成

#define HARD_SERVER_LIMIT 2560

保存退出编译apache

./configure –prefix=/usr/local/apache –enable-module=so –enable-module=rewrite –enable-shared=max –htdocsdir=/var/www &&

make &&

make install

#这里我们通过enable-module参数告诉设置脚本,我们需要启动so和rewrite模块,so模块是用来提DSO支持的 apache 核心模块,而rewrite模块则是用意实现地址重写的模块,由于rewrite模块需要DBM支持,如果在初次安装时没有编译进 apache,以后需要用到时需要重新编译整个apache才可以实现。为此除非你可以确定以后不会用到rewrite模块,否则还是建议你在第一次编译 的时候把 rewrite模块编译好。

enable-shared=max 这个参数的作用时编译apache时,把除了so以外的所有apache的标准模块都编译成DSO模块。而不是编译进apache核心内。

好了安装apache很简单的哦,启动apache看看

/usr/local/apache/bin/apachectl start

然后用ie看http://你的服务器地址。应该能看到熟悉的apache羽毛标志。

3.安装PHP4.3.4

软件获取:http://www.php.net/downloads.php

tar zvxf php-4.3.4.tar.gz

cd php-4.3.4

./configure

–prefix=/usr/local/php

–with-mysql=/usr/local/mysql

–enable-force-cgi-redirect

–with-freetype-dir=/usr

–with-png-dir=/usr

–with-gd –enable-gd-native-ttf

–with-ttf

–with-gdbm

–with-gettext

–with-iconv

–with-jpeg-dir=/usr

–with-png

–with-zlib

–with-xml

–enable-calendar

–with-apxs=/usr/local/apache/bin/apxs

make

make install

#我这里由于服务器需要用到GD库,所以加了一些支持GD的编译参数,GD直接用了redhat自带的GD库,大家没有安装的话可以从安装盘安 装,注意除了安装GD以外,还要安装libjpeg,libpng等库文件。另外–with-mysql=/usr/local/mysql指向你安装 mysql的路径。–with-apxs指向apache的apxs文件的路径。

vi /usr/local/apache/conf/httpd.conf

查找

在此范围添加

AddType application/x-httpd-php .php

AddType application/x-httpd-php-source .phps

然CPOPY PHP的配置文件

cp ../php4.3.4/php.ini.dist /usr/local/php/lib/php.ini

修改php.ini文件

register_globals = On

ok!重新启动一下apache服务器

/usr/local/apache/bin/apachectl restart

然后写个php测试页info.php:内容如下

phpinfo();

?>

正常的话,应该能看到php的信息了,恭喜你的Apche+Mysql+PHP安装成功

关于(*(void(*)())0)()

    前段时间看了这本C Traps and Pitfalls,看到里面有这样的一个语句:
   (*(void(*)())0)();

    初看此语句,让我头皮发麻,不寒而栗呀,我看了好半天书,也只是一知半解,后来在下面两个论坛上分别发一个帖子问了一下:
http://bbs.chinaunix.net/viewthread.php?tid=891271&extra=page%3D2
http://www.vckbase.com/bbs/viewtopic2.asp?rid=2869084&sf=92&forumID=1&pg=4

    首先这是一个函数调用,但是一个特殊的函数调用,在我们普通的C语言程序中是没有任何意义的,甚至不能执行的,我在VC6的环境下写了一个测试例子:
int main()
{
     (*(void(*)())0)();
     return 0;
}

    编译是通过了,但是却在执行的过程中出现了错误。在Linux下也进行了测试,也是编译通过,但运行出现了错误。
    然而,这个并不代表它没有用,它在一些特殊的环境中是有用的,比如在地址0处设置了跳转或是中断处理函数之类的,那么这个函数调用就有用了。
    总结一下我自己的理解和网上网友的理解:
   
    这是一个函数调用,它调用的是地址为0的函数。
如果我们令 f =
*(void(*)())0
那么这个上面的语句可以写成 (f)(),也就是f();这很显然是一个函数调用
而 void(*)()是一个指针类型,它是一个参数为空而返回值为void (实际上也是空)的函数指针类型,(void(*)())0就是把0强制转换成为一个函数指针,
我们可以这样理解
typedef void(*pp)();
   (*(pp)0)();

(void(*)())0这个函数指针指向一个地址为0的函数,如果前面再加一个星号*,那么就是对这个函数的引用,即(*(void(*)())0)就代表了这个函数,后面再加一个()就是对该函数的调用。