今天在调试反编译器,发掘几个网上下载的源码,是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
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