今天在調試反編譯器,發掘幾個網上下載下傳的源碼,是pb7寫的程式,總是報錯。最後ue打開仔細觀察,發掘在一個func内赫然放着2個函數體。在最開始開發反編譯器時,是從最簡單的struct和func開始開發的,是以當初為struct和func單獨寫了函數,而且認定func内隻有一個函數體。這就奇怪了。莫非是以前我想過的全局函數重載。。其實全局函數不能重載有時真的很煩人的。必須得寫幾個功能近似的。關鍵是函數名得另外取,不便于了解。其實我們知道,編譯後是不需要函數名,隻是一個查找和呼叫代号。
在網上搜一下,果然有篇2009的文章給出了提示,也就是在source edit下可以手工增補而實作重載。編譯器編譯時會像c,c++編譯器一樣将函數按照不同的param清單來命名。并在聯合編譯器,在其他對象内引用時,給出具體的函數名。這其實是利用源碼編輯直接繞過IDE的檢測。我前段嘗試在對象的create事件中手寫代碼來完成一些功能,貌似也是可以的。但是如果你一用畫闆,并修改了部分地方後儲存的話,create中的代碼就會被重新重新整理。也就是它們都是由IDE直接控制的,如同其他程式設計語言的工程檔案一樣。
但是也發現一個問題,下面的文章裡是寫成
global subroutine f_log (readonly string as_msg)
global subroutine f_log (throwable at, readonly integer ai_nu)
global subroutine f_log (readonly integer ai_nu)
但是從網上那個pbl中我看到重載的函數函數名不一樣,有一個函數它内部的兩個函數的參數表是不一緻的,但是另外還有參數表相同的情況,搞不清楚到底是怎麼回事。
因為我下載下傳的是pb源碼我打開pbl看到如下源碼:
//Here is Source in PBL or PBD,see it directly
//Comments:
global type f_addrecord from function_object
end type
forward prototypes
global subroutine uo_addrecord (datawindow dw, long row, string data)
global subroutine f_addrecord (datawindow dw, long row, string data, datawindow dw_grid)
end prototypes
global subroutine uo_addrecord (datawindow dw, long row, string data); long ll_insertrow
string ls_id
datetime ldtm_server_time
ls_id=dw.getitemstring(row,'id')
///
ll_insertrow=dw.insertrow(0)
dw.setitem(ll_insertrow,'id',data)
dw.setitem(ll_insertrow,'state','0')//将狀态設定為‘正常’
ldtm_server_time=f_get_server_time()
dw.setitem(ll_insertrow,'create_date',ldtm_server_time)
dw.setitem(ll_insertrow,'update_date',ldtm_server_time)
dw.setitem(ll_insertrow,'create_by',gs_username)
dw.setitem(ll_insertrow,'update_by',gs_username)
//建檔日期,修改日期均為伺服器的目前日期
//建檔人和修改人均為登入系統的使用者名
dw.setitem(row,'id',ls_id)
dw.scrolltorow(ll_insertrow)
dw.setcolumn(2)
end subroutine
global subroutine f_addrecord (datawindow dw, long row, string data, datawindow dw_grid); long ll_insertrow
string ls_id
datetime ldtm_server_time
//ls_id=dw.getitemstring(row,'id')
///
ll_insertrow=dw.insertrow(0)
dw.setitem(ll_insertrow,'id',data)
dw.setitem(ll_insertrow,'state','0')//将狀态設定為‘正常’
ldtm_server_time=f_get_server_time()
dw.setitem(ll_insertrow,'create_date',ldtm_server_time)
dw.setitem(ll_insertrow,'update_date',ldtm_server_time)
dw.setitem(ll_insertrow,'create_by',gs_username)
dw.setitem(ll_insertrow,'update_by',gs_username)
dw.setitemstatus(ll_insertrow,0,primary!,notmodified!)
//建檔日期,修改日期均為伺服器的目前日期
//建檔人和修改人均為登入系統的使用者名
//dw.setitem(row,'id',ls_id)
// dw.scrolltorow(ll_insertrow)
dw_grid.scrolltorow(ll_insertrow)
// dw_grid.setfocus()
// dw_grid.setcolumn(2)
end subroutine
原來的确是在源碼中就是寫的兩個不同的函數名。
實際上func雖然獨立為一個對象,但是也可以了解為存放函數體的一個容器。正常情況,一個func對象内隻有一個函數體,但是他跟uo,win一樣都具備存放多個函數體的條件。隻是IDE限制我們而已。
如果重載可以用,不過這種方法也太危險。因為畫闆會破壞手寫的部分。還是建議用nvuo,符合類的概念。擴充也比較友善。
文章http://topic.csdn.net/u/20090110/11/a9ab571b-535a-451e-a794-09c29178401b.html
全局函數重載原文:http://www.rgagnon.com/pbdetails/pb-0257.html
Overload a global function
thanks to Lawrence Sims for the following tip
You can overload global function objects in PowerBuilder with a simple trick. Just always edit them in source view, not in the painter. The following function (f_log) can be called like so:
f_log("Message To Be Logged")
f_log(t_throwable_caught, populateError (0, ""))
f_log(populateError(0, "Got to here ..."))
[f_log.srf]
just imported this file into a PBL to be able to use the overloaded f_log function)
global type f_log from function_object
end type
type prototypes
subroutine OutputDebugString (string as_msg) library "kernel32.dll" &
alias for "OutputDebugStringA"
end prototypes
forward prototypes
global subroutine f_log (readonly string as_msg)
global subroutine f_log (throwable at, readonly integer ai_nu)
global subroutine f_log (readonly integer ai_nu)
end prototypes
global subroutine f_log (readonly string as_msg);
OutputDebugString (as_msg)
end subroutine
global subroutine f_log (throwable at, readonly integer ai_nu);
string ls_message
ls_message = error.text
if isNull (error.text) or error.text = "" &
then ls_message = at.getMessage ()
OutputDebugString (error.object + "." + error.objectevent + &
": line " + string (error.line) + ": " + ls_message)
end subroutine
global subroutine f_log (readonly integer ai_nu);
if isValid (error) then
OutputDebugString (error.object + "." + error.objectevent + &
": line " + string (error.line) + ": " + error.text)
end if
end subroutine