祝愿大家身体健康!

 站点注册  找回密码
 站点注册

QQ登录

只需一步,快速开始

查看: 4705|回复: 0

[PB idea] PowerBuilder (pb)的扩展DLL开发(超级篇)(一)

[复制链接]

[PB idea] PowerBuilder (pb)的扩展DLL开发(超级篇)(一)

[复制链接]
ehxz

主题

0

回帖

56万

积分

管理员

积分
569893
贡献
在线时间
小时
2022-9-17 21:29:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?站点注册

×
FROM:https://blog.csdn.net/lxbin2003/article/details/118193313?spm=1001.2014.3001.5502
原创:lxbin2003


PB的扩展DLL开发(超级篇)

(PB史上第一次开放的开发技术)

PowerBuilder (pb)作为一个基于数据库的CS开发工具,在功能方面不够全面,需要使用 DLL做功能扩展。

通常为PB写DLL,有3种方法。

方法1:通用DLL。这种方式的DLL,所有能写标准DLL的语言都可以写。但缺点也比较明显,无法直接访问PB对象和属性、事件这些个性内容,不合适直接返回字符串,通过参数返回数据时,需要预分配内存,如果计算错误,会导致程序崩溃。

方法2:PBNI法(PowerBuilder Native Inte**ce),即官方开放式接口。此方法突破方法1的限制,可以访问PB内部对象、事件、属性。但也存在不同版本之间有一定的兼容性问题。目前广为使用。

这里,我介绍的是第3种方法,即 system library 方法。

一、system library 方法的来由

一次偶然的机会,逛到了http://www.vodacoder.com/Sources/fastfuncs这个网站,看到了全新的DLL for PB开发方法。不过,这个里面的DEMO都不够成熟,网上查不到任何与此相关的内容,官方也无相关内容。

于是本人开始潜心研究  (研究过程此处省略百万字...........)。初步掌握了system library 的开发方法,分享出来与大家共同研究。

二、system library 方法与方法1的区别

1、普通标准库DLL的函数声明:

function long test() library "test.dll"

如果是PB9以下版本的DLL,升级到高版本时,会自动加上;ansi,成了:

function long test() library "test.dll" alias for "test;ansi"

这里说一下,“;ansi”这个东西很恶心,误导害了一大堆PB程序员,以为高版本声明必须要加这么个玩艺。事实上,在使用winapi时,高版本有对应的函数,根本不需要;ansi这么个东西。PB升级时自动加上这个,纯属脱裤子放屁。

例如:

PB9:

FUNCTION ulong SetWindowText(ulong hwnd,ref string lpString) LIBRARY "user32.dll" ALIAS FOR "SetWindowTextA"

它升级到PB10以上,会自动变成

FUNCTION ulong SetWindowText(ulong hwnd,ref string lpString) LIBRARY "user32.dll" ALIAS FOR "SetWindowTextA;ansi"
。这个功能很垃圾。实际上应该是:

PB10及以上:

FUNCTION ulong SetWindowText(ulong hwnd,ref string lpString) LIBRARY "user32.dll" ALIAS FOR "SetWindowTextW"

注意,不加;ansi,而是最后的那个A改为W,表示使用UNICODE编码。

2、system library 的声明方式

看上面标准库的声明,它有个 library 关键词。那么system library方法,自然就应该是 system library 作为关键词了。system librar 就是PB自己内部函数的实现方式。

function long systest() system library "test.dll" alias for "systest"

注意:"system library"这个关键词,它告诉 PB,我是自己人,不是请来打工的那些个家伙。

实际上,我们在PB里用的函数,全部都是以system library方式存在于PBVMxxx.DLL中。

例如 :如果你不喜欢 MessageBox 这个名称,想使用 MsgBox 这个名称 ,而所有功能要一样。可以这样声明一个函数:

(假设是PB9) function int MsgBox(string title,string text) system library "pbvm90.dll" alias for "fnMessageBox"

(假设是PB10) function int MsgBox(string title,string text) system library "pbvm100.dll" alias for "fnMessageBox"

然后 MsgBox("","hello") 与 MessageBox("","hello")功能完全一样,只不过函数改了个名而已。用system librar方式声明的函数,即使是从PB9升级到高版本,PB也不会自动加上“;ansi”这么个垃圾东西,因为是自己人嘛,不是外来打工的家伙,待遇不一样的。

三、如何开始写自己的system library DLL

system library DLL有自己的固有特征,它通常是:

#include "pbSysLib.h" //这是我自己实现的一个头文件,具体作用就是加载PBVMxxxx.dll,导出相关SDK函数

  1. __declspec(dllexport) DWORD __stdcall FuncName(POB_THIS obThis,int nArgCount)
  2. {
  3.          BOOL isnull;
  4.          return 1;
  5. }
复制代码

FuncName 是函数名,POB_THIS obThis 这个由PB调用时自动传入,它指向一个结构,可以唯一标识一个PB的虚拟空间,或者也可以理解为一个session。int nArgCount 指的是本次调用有几个参数,而真正的参数放在obThis里的一个指针数组里,通过参数个数,可以去取这些个参数。

因此,system library DLL 函数还是比较简单的,这也符合PB这种古董级文物的身份,简单而有效。

接下来,就是使用PBVM的各种内部函数,来驾驶我们的各种功能,可以在C、C++里,访问PB的所有功用,并为PB扩展所有需要的功能。

这里就一个具体函数,做一些说明

PB里的声明:

function string TestRef(readonly string src,ref string dst) system library "PBJson.dll" alias for "TestRef"

使用时可以是:

string src,dst

src = "hello world"

TestRef(src,dst)

这时候dst的结果是:this is return by ref: [hello word]

DLL里的函数源码是:

  1. DLLEXPORT DWORD WINAPI TestRef(POB_THIS obThis, int nArgs)
  2. {
  3.          BOOL success = FALSE;
  4.          BOOL isnull = FALSE;
  5.          POT_LVALUE_INFO info = NULL;
  6.          TCHAR *lpSrc = (TCHAR *)ot_get_valptr_arg(obThis, &isnull);//取第一个参数,指针型,指向 src
  7.          POB_DATA lv = ot_get_next_lvalue_arg(obThis, &info); //取第二个参数,注意第二个参数是ref类型
  8.          POB_DATA v = NULL;
  9.          if (lv)
  10.          {
  11.                    POT_REF_PAK v = (POT_REF_PAK)lv->val.ptr; //获取得引用定义
  12.                    POB_DATA lpArg = ot_access_ref_data(obThis, v); //获取得引用定义里实际指向PB的那个变量,即上面的 dst
  13.                    if (lpSrc && lpArg && ob_get_data_type(lpArg) == STRING_TYPE) //判断,确实都是有效指针,并且第二个参数是 string  类型
  14.                    {
  15.                             TCHAR buffer[1024] = { 0 };
  16.                             _stprintf(buffer, _T("this is return by ref: [%s]"), lpSrc);
  17.                             ob_set_data_ptr(lpArg, ob_dup_string(obThis, buffer), STRING_TYPE, 1); //注意这里面有个ob_dup_string,它返回了一个从buffer复制出来的字符串的字符串,把这个变量绑定给引用的dst变量,而不是直接把 buffer 绑定给dst变量。
  18. /**
  19. 特别强调,这里的 ob_dup_string 是必不可少的。PB有自己的内存管理,这个复制的字符串,在PB函数生命周期结束后,它会被自动释放,内存回收。
  20. 这里如果写成:
  21.                             TCHAR *buffer = new buffer[1024];
  22.                             _stprintf(buffer, _T("this is return by ref: [%s]"), lpSrc);
  23.                             ob_set_data_ptr(lpArg, buffer, STRING_TYPE, 1);
  24. 也就是自己分配了内存,并且返回,这个函数调用后,PB是会崩溃的。原因是buffer没有使用PB的内存堆。
  25.                             TCHAR *buffer = ob_alloc_string(obThis,1024);
  26.                             _stprintf(buffer, _T("this is return by ref: [%s]"), lpSrc);
  27.                             ob_set_data_ptr(lpArg, buffer, STRING_TYPE, 1);
  28. 如果是这样,那就毫无问题了,因为TCHAR *buffer = ob_alloc_string(obThis,1024);是在PB自己的内存堆上分配 的内存,可以被PB正确释放回收。
  29. */
  30.                             success = TRUE;
  31.                    }
  32.          }
  33.          OB_DATA obReturn = { 0 };
  34.          ob_set_data_string(&obReturn, success, BOOL_TYPE, OB_INSTVAR_FIELD);
  35.          ot_set_return_val(obThis, &obReturn);
  36.          return 1;
  37. }
复制代码



如果你对system library相关开发方式感兴趣,可到QQ群624409252共享里大自在的专用目录下下载DEMO。
————————————————
版权声明:本文为CSDN博主「lxbin2003」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lxbin2003/article/details/118193313


共享共进共赢Sharing And Win-win Results
SYBASEBBS - 免责申明1、欢迎访问“SYBASEBBS.COM”,本文内容及相关资源来源于网络,版权归版权方所有!本站原创内容版权归本站所有,请勿转载!
2、本文内容仅代表作者观点,不代表本站立场,作者自负,本站资源仅供学习研究,请勿非法使用,否则后果自负!请下载后24小时内删除!
3、本文内容,包括但不限于源码、文字、图片等,仅供参考。本站不对其安全性,正确性等作出保证。但本站会尽量审核会员发表的内容。
4、如本帖侵犯到任何版权问题,请立即告知本站 ,本站将及时删除并致以最深的歉意!客服邮箱:admin@sybasebbs.com
您需要登录后才可以回帖 登录 | 站点注册

本版积分规则

免责声明:
本站所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:Admin@SybaseBbs.com

QQ|Archiver|PowerBuilder(PB)BBS社区 ( 鲁ICP备2021027222号-1 )

GMT+8, 2024-4-19 17:49 , Processed in 0.055580 second(s), 9 queries , MemCached On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表