多语言协作-操作系统级上应用面向对象方法的一个简单实例

为什么要多语言混合编程

答案很简单:

  • 每种语言各有所长,各有所短,计算机世界同人的社会一样,合作才是王道。
  • 合作才能取长补短,提高程序设计和实现的效率。

C擅长于底层,高明于效率;JAVA是网络开发的不二之选,Python编程简单,各种应用包很多,便于快速构建应用,但计算效率稍逊,MATLAB则有利于数学算法的原型验证,但闭源、庞大,难于直接用于工程。R语言专于统计,Julia是个新秀,也是集Python,R,MATLAB之优点,而又具C之计算效率的新型语言,但相对算法包还少。Octave与MATLAB几乎相同,代码兼容,只是缺少MATLAB的各种工具箱和专用函数,但在数据计算领域也是相当出色的。存在就是合理–德国哲学家黑格尔说: “凡是合乎理性的东西都是现实的; 凡是现实的东西都是合乎理性的。(黑格尔《法哲学原理》序) 。在计算机的世界里,也是如此,只不过规则比现实社会简单了许多。

混合编程的三种境界-亲密的,世俗的,商业的

用现代社会的合作与分工模式看待和解决计算机系统中多语言的协作问题,大致是没有错的。问题是要解决如何合作,在哪一个层次上合作,遵循哪些合作的规则,如何制定对合作失败的备选解决方案等等诸多难题。

亲密模式(非面向对象的模式)

  • 语言层面上的合作:这是在语言级上相互调用的问题,也是通常意义上的混合语言编程。例如,在Python中调用C,在JAVA中调用MATLAB等等,这是最深最紧的合作,是“朋友加兄弟的关系”,战斗的友谊如是鲜血凝成的,当然也会付出鲜血的代价! 一荣俱荣,一损俱损。各种语言都有或者通过第三方设计着自己的合作方法,接口,但我不主张用这种方式。最主要的原因是:这是一种紧耦合模式。其二,对程序员的知识要求太高,导致编程和后期维护成本都高。 其三,扩展性不好。反正紧耦合模式的所有缺点都是这种方式的缺点。爱得越深,伤得越重,----过于亲密的关系将导致撕裂时的血肉模糊。这是一种谈感情伤钱的方式。况且,从数学的角度看,有 N N N种语言,两两相接,就会有 N ! N! N种接口,从而成为一个全联通的网图,所以,现实中是没有哪种语言能做到能直接与其他语言相通的。有一首唱道:“爱的越深,伤的越深,就让我绝望中重生…”,如何重生?请看下面:

世俗模式(中小规模面向对象的模式)

  • 在操作系统层面上的合作:所有程序都跑在一个操作系统上,就象人都在同一个社会文化中生活,必须要遵循社会活动和相互关系的规范,即道德、风俗和法律;在计算机中,就是操作系统所维护的规则,消息传递 的方法以及调度协议等。只要操作系统不死,单独一个程序或功能是可替代的,就是常说的:离开了谁,地球照样转,所以,这是一种较为稳定的合作模式。因为这是在一种操作系统级上的面向对象方法:不同语言编写的应用程序自己是封装的,对外只提供如何使用以及使用的结果,又是可为新的程序所调用的(这是命令行程序的最大优点,因为调用是机对机的行为,GUI程序考虑的是机对人的交互,所以不满足这一点。),所以是可继承的。通过多参数的传递,又可以实现应用程序的多态性。因此,在操作系统层面上的合作方法是面向对象的方法。只要操作系统提供的数据交互方法足够简单,这种合作对程序员的知识和技巧要求就低了很多。例如,都通过标准输入输出STDIO进行数据交互和共享,以管道形式传递数据,就是一个不错的主意。STDIO和管道技术使数据接口标准化,做到与具体语言无关,就搭建成了一个公共的信息交互平台,各语言的应用程序以一种星型网络的拓扑结构与操作系统相连。并且接口标准只有一个!

商业模式(大规模面向对象的模式)

  • 在网络层面上的合作:这对应于社会生活的国际合作,必须遵循普世的价值观念,突破文化的障碍,相当于在计算机网络世界中不同操作系统上运行程序的合作:大家都以服务的模式进行数据交流好了。网络层面上的合作是最松耦合的,从而也是最Robust的。适合于更大型的分布式场境。TCP/IP及建立在其上的应用层协议是网络程序合作的基础。

本文只讨论中间一种模式:即在同一个操作系统下,在操作系统层面上的多语言混合编程问题。

实例

例如,我们要完成的任务是:与外部系统或网络中取得数据,对数据进行复杂计算或处理,可视化,将可视化结果以服务方式提交用户。我们用:

  • C 语言代码来写数据获取程序;
  • Octave(兼容MATLAB的开源科学计算环境)来实施具体计算;
  • Gnuplot工具来输出结果图。

以滤波器频率幅度响应为实例,设滤波器传递函数的分子分母系数为:

b=[0.0563 -0.0009 -0.0009 0.0563];  分子系数
a=[1.0000 -2.1291 1.7834 -0.5435];  分母系数

以下在Windows 10下实验。MATLAB程序为:

b=[0.0563 -0.0009 -0.0009 0.0563];
a=[1.0000 -2.1291 1.7834 -0.5435];
[h,w] = freqz(b,a,1024);
plot(w/pi,abs(h));

执行结果:
在这里插入图片描述

用Octave执行,结果一样:(直接命令行启动Octave-cli.exe)

任务很简单,完全不必要多语言编程完成,所以这里只是用来展示多语言编程的方法和过程。

为了从Octave中输出数据(而不是画图,一般计算程序不应负责可视化交互,在调试过程中除外),我们用fprinf函数取代plot函数。写成:

fprintf("%e\n",abs(h));

将Octave所在的路径添加到系统path路径中,将MATLAB代码写为文件freq.m :

【注:Octave下,扩展名,m不是必须的,可以是任意扩展名,无扩展名也行。】

b=[0.0563 -0.0009 -0.0009 0.0563];
a=[1.0000 -2.1291 1.7834 -0.5435];
[h,w] = freqz(b,a,1024);
fprintf("%e\n",abs(h));

然后通过命令行以Octave调用来执行freq.m脚本:

C:\> octave-cli.exe freq.m
...(前略,共1024行)
8.593363e-04
7.638517e-04
6.683682e-04
5.728854e-04
4.774034e-04
3.819220e-04
2.864411e-04
1.909605e-04
9.548020e-05
C:\>

还可以通过管道命令执行脚本(这是程序间数据能交互的关键!):

type freq.m | octave-cli.exe

就会在屏幕上打出计算结果数据来。而用重定向

type freq.m | octave-cli.exe > freq.dat

则生成了数据文件。最后,在gnuplot中,用命令

gnuplot> plot "freq.dat" u ($0/1024):1 w l

即得结果:

我们也可在gnuplot中直接执行管道指令,就可避免写数据文件。即:

gnuplot> plot "<type freq.m | octave-cli.exe" u ($0/1024):1 w l

所以,只要C代码程序能输出与<type freq.m相同的字串,就可以通过管道直接送到Octave中执行了,而执行结果又可通过重定向存入数据文件中供作图程序使用。

最简易(也是最土的,无实用处的)C代码如下:

//freqdemo.c
#include <stdio.h>
int main(int argc, char *argv[])
{
  puts("b=[0.0563 -0.0009 -0.0009 0.0563];");
  puts("a=[1.0000 -2.1291 1.7834 -0.5435];");
  puts("[h,w] = freqz(b,a,1024);");
  puts("fprintf(\"%e\\n\",abs(h));");  
  return 0;
}

【注意】其中puts("fprintf(\"%e\\n\",abs(h));");的写法。

编译并执行:(用Tiny CC的 tcc.exe 编译)

C:\Octave\Octave-4.4.1\bin>tcc freqdemo.c

C:\Octave\Octave-4.4.1\bin>freqdemo.exe
b=[0.0563 -0.0009 -0.0009 0.0563];
a=[1.0000 -2.1291 1.7834 -0.5435];
[h,w] = freqz(b,a,1024);
fprintf("%e\n",abs(h));

C:\Octave\Octave-4.4.1\bin>

于是,用管道命令就写成了:

freqdemo.exe | octave-cli.exe 

然后,编写gnuplot脚本freq.plt

set term png
set output "freq.png" 
plot "<freqdemo.exe | octave-cli.exe" u ($0/1024):1 w l
set output

执行之:

C:\Octave\Octave-4.4.1\bin>gnuplot freq.plt

则直接生成了png图片:freq.png,如下
在这里插入图片描述

程序执行过程解释如下:

  1. gnuplot 启动,调用执行脚本freq.plt
  2. 依据plt脚本,设置输出为png图片,并定下文件名为freq.png
  3. 执行作图语句plot
  4. 在plot中,首先执行freqdemo.exe,其输出通过管道符|送octave执行。Octave 收到freqdemo.exe送来的字符串后,当作代码解释并执行,输出数据到控制台。再由<重定向回gnuplot程序。
  5. plot收到数据后,按参数u ($0/1024):1 w l执行绘图并写png图片。
  6. 执行脚本后成功退出,并不显示任何信息,这符合Unix系统沉默是金是设计哲学。
C:\Octave\Octave-4.4.1\bin>gnuplot freq.plt

C:\Octave\Octave-4.4.1\bin>

利用这种方法,可以调用任何语言编写的可执行程序或脚本,从而实在在操作系统级的功能组装。组装者无需关注各功能的具体实现,只要各功能程序提供完整的运行方法和测试报告即可。

继而,还可以通过CGI(公共网关接口:Common Gateway Interface)或更高级的Java Servlet来向web服务器提供交互,形成web服务,作为网络级服务集成的原子服务,参与到大规模面向对象的模式的网络层面的合作中去。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值