PAD儲存過程以及相關的高階呼叫

terryisme發表於2009-03-03
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
MySubsmy_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".[@more@]http://blog.csdn.net/wwwabc0001/archive/2008/11/21/3346366.aspx

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/93029/viewspace-1018011/,如需轉載,請註明出處,否則將追究法律責任。

相關文章