关键字:progress 4GL IO language 开发 语言

1.过程调用
上一篇文章里简单提到调用一个内部的子过程只需要 run procedure-name(parameters). 并且子过程是不要预先声明的。
一个progress文件可以保存为.p结尾,表示是一个procedure文件。
简单地,你可以在命令行模式下:
prowin32 -p my.p

如果你的子过程比较大,或者需要反复调用,这时候你不可能每次在你的主程序里定义它,怎么办呢,可以把一个子过程存储为一个单独的.p文件,
调用的时候采用:
run 相对路径/my_subproc.p(parameters)

如果my_subproc.p和你的主程序在同一目录下,并且主程序所在目录为当前工作目录,则可以直接run my_subproc.p. 如果它是在一个子目录下,比如MySubs.目录结构如下:
main.p
MySubs/
MySubs/my_subproc.p
那么你可以run MySubs/my_subproc.p(parameters). 这里的路径分隔符之所以使用/而不是/是为了让其也可以在unix环境中运行。

下面具个例子,这些例子都存储在和主程序同目录:
/* 文件名:proc1.p  */
/*注释是使用 “/*你的注释*/" 来注明的,并且可以嵌套*/
define input parameter p1 as int no-undo.
define input parameter p2 as int no-undo.
define output parameter sum as int no-undo.
 sum = p1 + p2.

/*main.p*/

define variable mi as int no-undo.
run pro1.p(1,2,output mi).
message mi. /*mi = 3*/

注意:
如果输入参数类型是input,则在调用是实参可以省略。但是如果是input-output或者output是不可以省略的。

那么如果是函数怎么办呢?不要紧,好友另外一种文件类型 .i文件。

.i文件是一个include文件。比如说有一个 init.i:
define variable l_i as int no-undo.

function msum return int (input p1 as int,input p2 as int):
  return p1 + p2.
end function.

procedure showint:
define input parameter pi as int no-undo.

message pi.
end procedure.

则在你的主程序文件里可以这样引用它 {init.i}. 这样就相当于在这个地方定义了变量l_i和函数以及子过程。这一点有点像c语言里的宏定义。

比如main.p:
{init.i}
l_i = msum(1,2).
run showint(l_i).

这个完全等价与main2.p
define variable l_i as int no-undo.

function msum return int (input p1 as int,input p2 as int):
  return p1 + p2.
end function.

procedure showint:
define input parameter pi as int no-undo.

message pi.
end procedure.

l_i = msum(1,2).
run showint(l_i).

2.高级过程调用
有的时候你所使用的外部过程要使用中间变量,比如说引用参数;或者一系列的过程具有要共同完成一个任务,怎么办呢?
不要紧,你可以把这一系列的变量,过程还有函数都写在一个.p文件里。不过呢,要先说明一下几个关键字。
run前面说过了是用来调用过程的,现在在介绍它更多的属性。
run { proc_name | value(proc_name) } persistent set proc-handle (parameter1,parameter2,...,parametern).
run { proc_name | value(proc_name) } in proc-handle.
proc_name可以直接是过程的名字,也可以是一个字符串表达式, 比如 run my.p. 就等价于 run value("my.p").这个好处接下来再讲。
persistent表明你所调用的外部过程(这个属性只对外部过程调用有效,内部子过程无效)会一直存在,你若想要再次引用它内部的其他子过程时,就可以使用句柄proc-handle并且采用第二种方法.

dynamic-function("func-name" in proc-handle, param1,param2,...)是用来调用持久过程的内部函数的。
 
现在我们有一个外部过程文件mysubs.p,它包含了一个子过程,一个子函数:
/*----------------------------------------------------*/
define input parameter pi as int no-undo.

define variable li as int no-undo.

li = pi.
MESSAGE li.

procedure add1:
    li = li + 1.
end procedure.

function multi return int(input p1 as int):
    return li * p1.
end function.

/*-----------------------------------------------------------*/
当你要调用的时候,可以用如下方法main3.p:

define variable h1 as handle no-undo.
run mysubs.p persistent set h1(2). /*注意,这个时候mysubs.p中的li已经被初始化为2了*/

define variable mi as int no-undo.
mi = dynamic-function("multi" in h1,3). /*调用*/
MESSAGE   mi . /*mi = 6 = 2*3 */

run add1 in h1. /*li = 3*/

mi = dynamic-function("multi" in h1,3).
MESSAGE mi. /*mi = 6*/

delete procedure h1. /*使用完删除对象释放内存*/

3.高级过程调用(续)
上面讲到了调用的时候过程名可以是一个字符串表达式。我想因为没有函数指针之类的东西,这样子可以近似的代替函数指针吧。
define variable func-names as char extent 3. /*定义了一个维数为3的字符串数组*/
func-names[1] = "addd".
func-names[2] = "minus".
func-names[3] = "product".

function addd return int (input p1 as int, input p2 as int):
return p1 + p2.
end function.

function minus return int (input p1 as int, input p2 as int):
return p1 - p2.
end function.

function product return int (input p1 as int, input p2 as int):
return p1 * p2.
end function.

define variable i as int no-undo.

do i = 1 to 3:
    message dynamic-function(func-names[i],1,2).
end.

func-names[1] = "proc1".
func-names[2] = "proc2".
func-names[3] = "proc3".

procedure proc1:
  message 1.
end procedure.

procedure proc2:
    message 2.
end procedure.

procedure proc3:
    message 3.
end procedure.

do  i = 1 to 3:
    run value(func-names[i]).
end.
/*----------------------------------------------*/
另外一个大大的好处就是你可以直接把一个过程的名字作为参数传送进来,当然前提是这个文件存在。 c语言的解决方法是把过程或者函数写在一个dll文件里,通过loadlibrary和getProcAddress实现。比如你可以在数据库中存储被调用过程的名字,对不同的客户开发不同的程序,设置不同的名字即可。
当然你说也可以用select(vb用)或者switch(c/c++/java用),不过一旦编译之后就不能添加新的了吧。

4.全局变量

progress的全局变量的定义是这样的:
define [[new [global]] shared] variable g_my_Variable as dataType no-undo.
不带global参数的称谓局部共享变量。两者的区别是,局部共享变量可以被被调用程序访问,并且可以继承。
比如p1.p定义了define new shared variable mshare as char no-undo. 接着p1.p调用了p2.p,p2.p又调用了p3.p,那么在p2.p和p3.p里都是可以访问到mshare的。
全局共享变量的不同之处在于,如果定义一个全局共享变量在p2.p,p1.p在调用p2.p之后调用p4.p,那么p4.p是仍然可以访问全局共享变量的,即使创建它的程序p2.p已经结束了。为什么呢,是因为它存在于全局共享内存里。所以一旦创建,它就一直在那里,直到整个应用程序结束。
p1.p
/*----------------------------------------------*/
define new shared variable mshare as char.
mshare = "shared".
run p2.p.
run p4.p.

p2.p
/*---------------------------------------------*/
define new global shared gvar as char.
define shared variable mshare as char.  /*你需要声明这个共享变量*/
gvar = "global".
message mshare + " in p2.p".
 
p3.p
/*----------------------------------------------*/
define shared variable mshare as char.
define shared variable gvar as char.
message mshare + " in p3.p" + gvar + " in p3.p".

p4.p
/*-----------------------------------------------*/
define shared variable gvar as char.
message gvar + " in p4.p".

progress的高级过程调用以及全局变量相关推荐

  1. Intel汇编程序设计-高级过程(上)

    第八章 高级过程 8.1 简介 本章主要讲: 堆栈框架 变量作用域和生存期 对战参数的类型 通过传递值或者传递引用来传递参数 在堆栈上创建和初始化局部变量 递归 编写多模块程序 内存模型和语言关键字 ...

  2. RPC(Remote Procedure Calls)远程过程调用

    很长时间以来都没有怎么好好搞清楚RPC(即Remote Procedure Call,远程过程调用)和HTTP调用的区别,不都是写一个服务然后在客户端调用么?这里请允许我迷之一笑~Naive!本文简单 ...

  3. 从核心概念和技术层面着眼,系统化认识RPC 2017-09-26 张旭 InfoQ 作者|张旭 编辑|田光 RPC(Remote Procedure Call),即远程过程调用,是一个分布式系统间

    从核心概念和技术层面着眼,系统化认识RPC 转自:https://mp.weixin.qq.com/s/6AX2-zjvcpesSe93HihVoA 2017-09-26  张旭  InfoQ 作者| ...

  4. 远程过程调用RPC简介

    RPC(Remote Procedure Call, 远程过程调用):是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的思想. RPC是一种技术思想而非一种规范或协议,常见RPC技术 ...

  5. 汇编 无条件转移和过程调用指令

    (1)JMP无条件转移指令 指令格式: JMP 目的 指令功能: 使程序无条件地转移到指令中指定的目的地去执行. 这类指令又分为两种类型: 第一种类型:段内转移或近(NEAR)转移,转移指令的目的地址 ...

  6. 进程间通信 IPC 的本地过程调用 LPC(Local Procedure Call)和远程过程调用 RPC(Remote Procedure Call)

    进程间通信(IPC:Inter-Process Communication)是在多任务操作系统或联网的计算机之间运行的程序和进程所用的通信技术.有两种类型的进程间通信(IPC). 本地过程调用(LPC ...

  7. 计算机系统 过程调用

    文章目录 过程调用概述 过程调用参数传递 过程调用概述 在这里插入图片描述 过程调用参数传递

  8. rpc 服务器不可用_什么是远程过程调用RPC

    背景:  最近在开发中接触到微服务的一些概念,并且为其他业务组通过URL请求的方式提供了我们本地接口.  其中涉及到了,注册方法,发送和接收脚本,确定调用的URL,鉴权数据.从而引出今天要讲内容RPC ...

  9. Thrift架构~从图中理解thrift,它事实上是一种远程过程调用

    thrift为我们简化了tcp通讯,它可以使用我们方便的建立各种语言的服务端与客户端,并实现客户端对服务器的远程过程调用,简单的说就是服务器通过thrift架构对外开放一些接口,并自己实现这些接口,如 ...

最新文章

  1. 今日 Paper | 协作蒸馏;人脸反欺骗;人脸表示;3D-CariGAN等
  2. PTP4L 简化版本OC模式
  3. python应该怎么自学-学习Python最正确的步骤
  4. DL之DNN优化技术:DNN优化器的参数优化—更新参数的四种最优化方法(SGD/Momentum/AdaGrad/Adam)的案例理解、图表可视化比较
  5. random---伪随机数生成器
  6. 【Linux进程、线程、任务调度】一 Linux进程生命周期 僵尸进程的含义 停止状态与作业控制 内存泄漏的真实含义 task_struct以及task_struct之间的关系
  7. 基于阈值的损失函数_推荐 :常见损失函数和评价指标总结(附公式amp;代码)...
  8. java 异常怎么划分_java异常的分类
  9. ESXI5.1 数据备份与恢复
  10. AcWing 1922. 懒惰的牛(前缀和 or 双指针)
  11. curl安装失败/区块链配置
  12. SORPAS-焊接仿真模拟软件
  13. win7 VS2010 Visual Assist X破解
  14. DRF Serializer序列化器使用
  15. HTML header 标签的用法
  16. springboot DataSource
  17. c 语言输出省份面积和高度,中国省份面积
  18. 韦东山第二期课程内容概要
  19. Windows神软Classic Shell停更!经典开始菜单永别了
  20. dva处理_关于dva框架的二三事

热门文章

  1. python柱形图绘制_Python数据分析:柱形图的绘制方法
  2. 地理信息系统的元数据、主数据、参考数据之间的区分
  3. AcWing算法基础课 第一讲小结(持续更新中)
  4. c语言sqlite3写数据类型,在sqlite数据库中,int类型不等于integer数据类型
  5. 电商行业分析指标体系拆解下钻
  6. 开发脚手架及封装自动化构建工作流
  7. ZIP压缩算法详细分析及解压实例解释
  8. aptx与ldac音质区别_蓝牙协议LDAC和aptx的区别?
  9. Save More Mice (贪心 二分)
  10. c语言解除宏定义_3.3.5 取消宏定义和重新定义宏