Blog

赋比兴是作诗时内心感动的由来

Content #

赋者,敷也,敷陈其事而直言之者。比者,以彼物比此物也。兴者,先言他物以引起所咏之词也。——朱熹《诗集传》

我简单地介绍了中国最古老的《诗经》所提供给我们的三种作诗的方法——赋、比、兴。不过大家一定要注意:它们是作诗的方法,而不仅仅是作诗的技巧,它们所揭示的,其实是作诗的时候你内心感动的由来:

一个是由外物引起你内心的感动,一个是你内心先有了感动然后用一个外物的形象来表现,一个是你就直接用你说话的口吻和语气把你的感动表现出来。

这就是古人所总结出来的诗歌中三种表现兴发感动的方式。

From #

人间词话七讲

浣溪沙·修到南屏数晚钟

Content #

词之为体,要眇宜修。能言诗之所不能言,而不能尽言诗之所能言。诗之境阔,词之言长。

这“要眇”和“宜修”都是《楚辞·九歌》里边的语言,是形容湘水上的一位女神,说她不但有一种深微幽隐的美,而且还有一种修饰的美。王国维说词也具有这样的一种美,说词的这种美能够传达出诗所不能够传达的内容,但不能够完全传达出诗所能够传达出来的内容。

今天,我们要用晚清的一位遗民词人陈曾寿的一首《浣溪沙》词作例子,来看一看词能够传达出哪些个诗所不能传达的东西。我先读一下这首词:

修到南屏数晚钟。目成朝暮一雷峰。黄深浅画难工。千古苍凉天水碧,一生缱绻夕阳红。为谁粉碎到虚空?

诗都有一个题目,比如杜甫的《闻官军收河南河北》,那是在唐代的安史之乱中,杜甫在剑门关外听到官军收复了河南河北的消息,喜极而作。诗的标题就已经把要说的意思说得很明白了。而词呢?词的妙处在于它常常没有题目,《浣溪沙》是音乐的词牌而不是题目。

赋比兴是作诗时内心感动的由来。陈曾寿的曾祖陈沆写了《诗比兴笺》。这个“比兴”,就是从《诗经》发展下来的中国传统的诗歌理论,但他更注重的是比的方法,即所谓“言在此而意在彼”。上面我所说的都是诗,那么词呢?如果说,词也常常在表面上说的是一种东西,却引起读者联想到另外的东西,那也是“比兴”吗?我以为,那与传统的诗论所说的“比兴”是不一样的。这我们还是要看完了陈曾寿的这首词,才能知道它们是怎样的不一样。

陈曾寿经历了清朝的灭亡、军阀的混战、日本的挟持,经历了这种种的乱离与灾难,终于从东北回到了杭州,住在了西湖边上南屏山下,所以他说:我真是“修到南屏数晚钟”。这“修到”两个字之中实在有太多的感慨在里边。而且你看,他还不是“听晚钟”而是“数晚钟”。这个“数”字也很妙,是那每一声每一声的晚钟,其实都是他内心的寂寞和哀感啊。这就是词的要眇幽微了。一首好词中的每一个字,都起着非常微妙的作用。

下一句,“目成朝暮一雷峰”的“目成”两个字,就仅仅是“看见了”这么简单吗?读中国古典诗歌是需要有古典的修养做基础的,你的古典修养越丰富,你从中体会到的意思就越多。“目成”两个字有出处,出于《楚辞》的《九歌》。《九歌》本来是楚地祭祀鬼神时所唱的歌,最初可能是比较粗浅的,但是它经屈原改写过,其中包含了屈原的感觉和感情,所以就有了很深厚的意思。按楚地的习惯,祭神如果请的是男神仙就要用女巫,如果请的是女神仙就要用男巫。《九歌》里有一首《少司命》,是男性神仙,所以用了女巫的口吻。其中有两句说:“满堂兮美人,忽独与余兮目成。”说是在祭祀的大厅里虽然有这么多美人,可是那降临的神仙只对我看了一眼,我们两个就一见倾心了。这就是古人所说的“目成心许”啊!所以“目成”这个词,它是包含有感情的投入这样一种意味在里边的。“目成朝暮一雷峰”——我抱着如此专一的感情,从早晨到晚上就看着这唯一的雷峰塔,我已经把我所有的感情都寄托在它上面了。而这雷峰塔呢?它真是美丽极了,黄昏时的满天晚霞染就了从橙红到浅黄之间错综复杂的、深深浅浅的多层颜色,没有一个画家能够用人工的色彩把它画出来,那真是“黄深浅画难工”。

雷峰塔是北宋初期建造的,而陈曾寿来到这里是什么时候?已经是民国初期。从北宋到民国,千年往事都已经过去了,这雷峰塔就一直矗立在青山绿水的西湖边,阅尽了人间千古兴亡。所以是“千古苍凉天水碧”。那么这个“天水碧”,看起来不就是说上边是青天下边是绿水吗?可是你一定要知道中国古典诗词的妙用。写旧体诗和写新诗是完全不一样的,写新诗可以由你自己想出一个新的语汇,找出一个你认为恰当的语言;而写旧体诗就有一个古典的背景,它的文本里边的每一个符号都是带有古典传统的。这“千古苍凉天水碧”里边其实藏着一个故事。大家都知道五代十国里的南唐,南唐的李后主是很有名的,他是一个有才华的诗人,却不是一个好皇帝。这个人非常喜欢歌舞宴乐,养了一大批歌儿舞女,这些歌儿舞女需要做漂亮的衣服来穿,那么有一次,他们就把一匹丝绸染成浅蓝的颜色,晾在外面,到夜间忘记了收进来,第二天早上一看,经夜间的露水浸染过的这匹丝绸,它的颜色比他们以前染过的任何一匹丝绸都漂亮。于是,这种蓝色就被起名叫作“天水碧”。可是你要知道,古人认为很多盛衰兴亡的事情都是有预兆的。宋朝的皇帝不是姓赵吗?赵姓的郡望就是天水——所谓“郡望”就是指一个姓氏中最有名望的家族的所在。而这个“碧”字呢,在古代是个入声字,读音同“逼”字。所以,“天水碧”就预示了南唐将要亡于北宋的这样一个史实。

南唐是亡于北宋了,那么现在陈曾寿所经历的,又是清朝的败亡。所以他说:雷峰塔在西湖边阅尽了多少朝代的盛衰兴亡,而我陈曾寿在西湖边上,和雷峰塔一起,也看到了那么多的盛衰兴亡。所以你们看,这首词表面上都是风景,但内里却隐藏着很多的感慨悲哀。在历史上,对待盛衰兴亡和改朝换代,不同的人有不同的态度。像五代的冯道,曾历仕后唐、后晋、后汉、后周四朝,还得意洋洋地自称“长乐老”。那么陈曾寿呢?清朝已经灭亡了,而且他自己是一个汉人,为什么要做清朝的遗民,为什么对那个已经成为日本傀儡的溥仪还有那么深的感情呢?这就是古人所说的“看得破,忍不过”了。陈曾寿本来是溥仪皇后婉容的老师,溥仪非常信任他,在离开天津时把天津的一切事情都交托给他,到了东北以后又几次叫他去。他不愿意在伪满做官,不肯去,最后溥仪说,你来管我们祖先的陵墓吧,他不得已才去了东北,但溥仪祖先的陵墓后来好像也被日本人霸占了。陈曾寿为什么不能够断然离开溥仪?因为溥仪是个小皇帝啊,他即位的时候才是个三岁的孩子,清朝的腐败和灭亡并没有他的责任。其实像王国维、陈宝琛他们也是一样的,但他们这种感情放到现在确实是很不容易说清楚。正是由于陈曾寿从内心摆脱不了,所以他无可奈何。那么他这些感情的来龙去脉,我用了这么多的话来解释,而陈曾寿他也说了这么多话吗?没有啊,人家陈曾寿只是说:“一生缱绻夕阳红。”你看他用的这“缱绻”两字,都是绞丝边,都是缠绵不断的,都是双声叠韵的,那就是他那种剪不断理还乱的感情啊。而且人的一生留恋什么不好?像陶渊明“抚孤松而盘桓”,他留恋的是松树,因为松树是独立的、挺拔的、在霜雪中都不凋零的。而你陈曾寿为什么留恋夕阳呢?你这一生缱绻不能摆脱的,难道就是夕阳那即将消逝的颜色吗?

而且还不仅如此,如果眼前还有那个雷峰塔,还有那[插图]黄深浅的背景,还有那夕阳红的颜色,那么你还有一个可以留恋的对象,还可以“目成朝暮”,还可以“一生缱绻”,而实际上,现在连这个夕阳红的雷峰塔也没有了。在陈曾寿写这首词的那一年,雷峰塔倒了。所以他说:“为谁粉碎到虚空?”为什么连这一点点聊以缱绻的对象都不能够保留呢?

所以你看这首词,它的“目成”两个字的深厚的意思,它的“天水碧”这样的典故,它的“缱绻夕阳红”的那一份心情,都是非常微妙的。这些东西如果用诗来写就变得落实了:你说你眷恋故国?你说你忠爱缠绵?那太落实了,你不会那样说的。这也就是王国维《人间词话》说的“词之为体,要眇宜修,能言诗之所不能言,而不能尽言诗之所能言”了。而且你看,这么短的一首词我为什么讲了这么多?因为在短短的七个字里边他就有说不完的意思,给读者非常丰富的联想。这就是王国维《人间词话》所说的“词之言长”啊。

From #

人间词话七讲

共享库的链接名(Link Name)

Content #

需要链接一个libXXX.so.2.6.1的共享库,只需要在编译器命令行里面指定-lXXX 即可,可省略所有其他部分。编译器会根据当前环境,在系统中的相关路径(往往由-L参数指定)查找最新版本的“XXX”库。

这个“XXX”又被称为共享库的链接名(Link Name)。

不同类型的库可能会有同样的链接名,比如C语言运行库有静态版本(libc.a)和动态版本(libc.so.x.y.z)的区别,如果在链接时使用参数“-lc”,那么链接器会根据输出文件的情况(动态/静态)来选择适合版本的库。比如ld使用“-static”参数时,“-lc”会查找libc.a;如果使用“-Bdynamic”(这也是默认情况),它会查找最新版本的libc.so.x.y.z。

From #

程序员的自我修养

链接时不产生符号信息

Content #

除了使用“strip”工具,还可以使用ld的“-s”和“-S”参数,使得链接器生成输出文件时就不产生符号信息。

“-s”和“-S”的区别是:“-S”消除调试符号信息,而“-s”消除所有符号信息。

也可以在gcc中通过“-Wl,-s”和“-Wl,-S”给ld传递这两个参数。

From #

程序员的自我修养

共享库脚本

Content #

共享库还可以是符合一定格式的链接脚本文件。通过这种脚本文件,可以把几个现有的共享库通过一定的方式组合起来,从用户的角度看就是一个新的共享库。比如可以把C运行库和数学库组合成一个新的库libfoo.so,那么libfoo.so的内容可以如下:

GROUP( /lib/libc.so.6 /lib/libm.so.2)

这里的脚本与LD的脚本从语法和命令上来讲没什么区别,它们的作用也相似,即将一个或多个输入文件以一定的格式经过变换以后形成一个输出文件。也可以将这种共享库脚本叫做动态链接脚本,因为这个链接过程是动态完成的,也就是运行时完成的。

From #

程序员的自我修养

共享库构造和析构函数

Content #

GCC提供了一种共享库的构造函数,只要在函数声明时加上“_attribute_((constructor))”的属性,即指定该函数为共享库构造函数,拥有这种属性的函数会在共享库加载时被执行,即在程序的main函数之前执行。如果我们使用dlopen()打开共享库,共享库构造函数会在dlopen()返回之前被执行。

与共享库构造函数相对应的是析构函数,可以使用在函数声明时加上“_attribute_((destructor))”的属性,这种函数会在main()函数执行完毕之后执行(或者是程序调用exit()时执行)。如果共享库是运行时加载的,那么使用dlclose()来卸载共享库时,析构函数将会在dlclose()返回之前执行。声明构造和析构函数的格式如下:

void __attribute__((constructor)) init_function(void);
void __attribute__((destructor))  fini_function (void);

如果我们使用了这种析构或构造函数,那么必须使用系统默认的标准运行库和启动文件,即不可以使用GCC的“-nostartfiles”或“-nostdlib”这两个参数。因为这些构造和析构函数是在系统默认的标准运行库或启动文件里面被运行的,如果没有这些辅助结构,它们可能不会被运行。

如果我们有多个构造函数,那么默认情况下,它们被执行的顺序是没有规定的。如果我们希望构造和析构函数能够按照一定的顺序执行,GCC为我们提供了一个参数叫做优先级,我们可以指定某个构造或析构函数的优先级:

void __attribute__((constructor(5))) init_function1(void);
void __attribute__((constructor(10))) init_function2(void);

对于构造函数来说,属性中优先级数字越小的函数将会在优先级大的函数之前运行;而对于析构函数来讲,则刚好相反。这种安排有利于构造函数和析构函数能够匹配,比如某一对构造函数和析构函数分别用来申请和释放某个资源,那么它们可以拥有一样的优先级。这样做的结果往往是先申请的资源后释放,符合资源释放的一般规则。

From #

程序员的自我修养

安装共享库

Content #

方法一 #

  1. 将共享库复制到某个标准的共享库目录,如/lib、/usr/lib等
  2. 运行ldconfig

缺点:需要系统的root权限。

方法二 #

  1. 建立SO-NAME软链接建立SO-NAME需要指定共享库所在的目录:

    $ldconfig –n shared_library_directory
    
  2. 编译程序时指定共享库的位置

    • 使用参数“-L”和“-l”,分别用于指定共享库搜索目录和共享库的路径。
    • 使用“-rpath”参数。
    • 使用环境变量LD_LIBRARY_PATH。

From #

程序员的自我修养

LD_DEBUG

Content #

这个变量可以打开动态链接器的调试功能,当我们设置这个变量时,动态链接器会在运行时打印出各种有用的信息,对于我们开发和调试共享库有很大的帮助。比如我们可以将LD_DEBUG设置成“files”,并且运行一个简单动态链接的 HelloWorld:

$LD_DEBUG=files ./HelloWorld.out

动态链接器打印出了整个装载过程,显示程序依赖于哪个共享库并且按照什么步骤装载和初始化,共享库装载时的地址等。

LD_DEBUG还可以设置成其他值,比如:“bindings”显示动态链接的符号绑定过程。“libs”显示共享库的查找过程。“versions”显示符号的版本依赖关系。“reloc”显示重定位过程。“symbols”显示符号表查找过程。“statistics”显示动态链接过程中的各种统计信息。

From #

程序员的自我修养

LD_PRELOAD

Content #

在LD_PRELOAD里面指定的文件会在动态链接器按照固定规则搜索共享库之前装载,它比LD_LIBRARY_PATH里面所指定的目录中的共享库还要优先。无论程序是否依赖于它们,LD_PRELOAD里面指定的共享库或目标文件都会被装载。

由于全局符号介入这个机制的存在,LD_PRELOAD里面指定的共享库或目标文件中的全局符号就会覆盖后面加载的同名全局符号,这使得我们可以很方便地做到改写标准C库中的某个或某几个函数而不影响其他函数,对于程序的调试或测试非常有用。

系统配置文件中有一个文件是/etc/ld.so.preload,它的作用与LD_PRELOAD一样。这个文件里面记录的共享库或目标文件的效果跟LD_PRELOAD里面指定的一样,也会被提前装载。

From #

程序员的自我修养

动态链接器查找共享库的顺序

Content #

动态链接器会按照下列顺序依次装载或查找共享对象(目标文件):

  1. 由环境变量LD_LIBRARY_PATH指定的路径。
  2. 由路径缓存文件/etc/ld.so.cache指定的路径。
  3. 默认共享库目录,先/usr/lib,然后/lib。

From #

程序员的自我修养