前往Shuct.Net首页

Shudepb PB反编译专家长时间以来,为业内同类软件事实上的唯一选择.细节,彰显专业.态度,决定品质.

关于PBKILLER的搜索

PBNI VC调用PB的元件,什么是PBNI,外部函数,反破解,防止PBKILLER 您现在的位置:网学>>论文>>论文导航>>pb PBNI VC调用PB的元件,什么是PBNI,外部函数,反破解,防止PBKILLER pb 2013-10-2  下载论文 发表评论 复制论文网址 上传用户:boya5227 【pb栏目提醒】:网学会员--在 pb编辑为广大网友搜集整理了:PBNI VC调用PB的元件,什么是PBNI,外部函数,反破解,防止PBKILLER - 人力资源绩等信息,祝愿广大网友取得需要的信息,参考学习。 BNI 是powerbuilder 的本机扩展是很强大的东东最近因为工作需要稍作了点研究希望对未做过PBNI的朋友有所帮助。 用最简单的的话来讲不准确就是Java C 里可以加载PB的虚拟机利用PB的对象语言主要是利用PB在某些方面的强大功能让他们能很好的结合。 PB 安装目录 SDK下的文件非常重要要阅读下PB自带的帮助文档。 Powerbuilder9 的版本只支持 vs610.5的最高支持到VS2005 如果要想让PBNI 支持到VS2008并且集成到appwiz里需要手动来做。 SybasePb105PowerBuilder 10.5SDKPBNIWizardsVCWizardsPBNIWizard8此目录下的deploy.bat 文件有时执行不一定成功手动就可以按照里边的步骤做做完后SybasePb105PowerBuilder 10.5SDKPBNIWizardsVCProjects 8.0这个目录下的文件PBNIWizard.vsz 文件用UE打开将8.0 改为9.0 再复制到相应目录就可以在VS2008里用向导创建PBNI工程了。 还有一点要提醒的是一定要使用向导来创建PBNI否则很容易挂哦 谈论 PowerBuilder 9开发技术讲座-PowerBuilder Native InterfacePBNI华软编程论坛 PowerBuilder 9开发技术讲座— PowerBuilder Native InterfacePBNI PowerBuilder 9现在对于其他开发语言的支援有了全新的突破在以往使用 PowerBuilder开发程式时要和C或是Java程式互通有无是有一些折衷的办 法但是总是没有办法做到简易而且全面性的支援。 现在只要透过PowerBuilder 9的PBNI技术就可以让PowerBuilder的程式呼叫Java或是在一个C的程 式中引用PowerBuilder NVO物件函数。 以往的PowerBuilder程式只能够透过外在函数呼叫的方式来存取C/C的函 数但在PowerBuilder 9.0之中扩增了一项强而有力的介面「PowerBuilder Native Interface」简称PBNI。 透过PBNI的开发方式PowerBuilder开发人员 不仅可以使用物件导向的方式来存取C/C函数而且还可反向地让C/C程式 呼叫PowerBuilder之中的物件达到应用程式的整合。 更甚者在藉由JNI与 PBNI两者的结合Java应用程式也可双向地与PowerBuilder程式沟通。 何谓PBNI 在谈什么是PBNI之前我们先来谈谈下面三个问题 1.开发人员有办法用PowerBuilder程式呼叫C或是C的程式吗 2.开发人员有办法用PowerBuilder程式呼叫一些外部元件像是Java EJB元件、 Web Service元件、Java Class程式等诸如此类的元件吗 3.开发人员有办法用反过来用C或是C呼叫已经使用PowerBuilder开发好 的程式吗 上述三个问题在过去的PowerBuilder其实都可以做到某种程度的地步只是都 有些问题。 传统上使用PowerBuilder开发上述的程式时如果要呼叫C或是C 的程式是可以使用宣告外部函数的方式来使用一个已经撰写好的DLL函数 例如 FUNCTION ulong GetSysColor int index LIBRARY quotUSER32.DLL” FUNCTION boolean sndPlaySoundA string SoundName uint Flags LIBRARY quotWINMM.DLLquot 可是如果是下面的程式呢 BOOL EnumWindowsWNDENUMPROC lpEnumFunc LPARAM lParam 这个可是个大问题了因为这个Windows DLL Function中会用到所谓的「Callback」 函数的技术所谓的Callback Function指的是今天有A和B两个物件在程式中 A物件呼叫B物件的Function而在该B物件的Function又会回头呼叫A物件的 其他Function这就叫「Callback」。 在PowerBuilder呼叫C的Function后在这 个C的Function中要再回头呼叫PowerBuilder的函数是不可能用引用外部函数的 方式来达到这个目地的。 除了Callback Function使用困难之外使用外部函数也 有资料型态的限制以及没有办法使用物件导向的方式开发等种种的困难及问 题。 再来谈谈PowerBuilder呼叫外部的元件的方法在以前能够让PowerBuilder呼叫 EJB元件就只能透过一些协力厂商开发的「COM Bridge」让PowerBuilder程 式透过COM元件来呼叫Java程式。 至于要让Java或是C来呼叫PowerBuilder 程式的话过去最常见的方法就是把这个PowerBuilder的程式包装成为「OLE automation server」。 这些方法都不是一个真正解决的好方法说穿了这些方法 跟本就没有办法直接和PowerBuilder的核心「PowerBuilder Visual Machine」做沟 通所以在过去的版本的PowerBuilder是一直有这种和其他语言程式不能沟通 的困扰这也是大家一直认为PowerBuilder是一个封闭不开放的开发工具。 PowerBuilder 9这个版本有几个突破性的技术而PBNI就是其中一个。 所谓的 PBNI PowerBuilder Native Interface指的是PowerBuilder提供一个「原生介面 Native Interface」透过这个介面可以使得PowerBuilder提高了对其他程式语言 的扩展能力比方说透过该介面可以存取任何类型的外部应用应用程式或是让 外界其他的程式语言存取或是呼叫PowerBuilder开发的程式下面是一个简单的 PBNI的示意图 此主题相关图片如下1.jpg 在上面这张图中PBNI提供了两道让外界可以和PowerBuilder核心PBVM的介 面窗口第一个对外的窗口是指在图的右半边我们可以开发「PB Extension」 PB Extension其实最后会变成DLL透过该技术C或是C的DLL程式可以包 装成为一个「PBD」的档案而该PBD的档案就可以在开发程式时加到Library Search Path中让PowerBuilder直接存取PBD里的物件函数你可以把它当作是 一个很像PowerBuilder NVO的东西来对待它。 第二个对外的窗口是指在图的左半 边你可以把PowerBuilder Virtual Machine 「内嵌」到一个C的应用程式中 在C程式中就可以直接呼叫PowerScript Function。 PBNI的元素 PBNI提供了一些基本的元素透过这些元素程式开发人员可以快速的引用外 部程式语言下面是常见到的PBNI元素 PBNI提供的介面Interface: IPB_VM这个介面的作用在于当你要用C或是其他的程式语言来 呼叫PowerBuilder开发的程式或是你希望要和PowerBuilder的核心 「PBVM」进行互动或是沟通协调你可以使用这个介面。 IPB_Session这是一个抽象的介面这个介面可以用来定义诸如存取 PowerScript里面的资料、建立PowerBuilder物件和呼叫PowerScript函数 操作的方法 IPB_Value这个介面你可以把它想像成是它就是代表PowerBuilder的 值。 这些值可以是PowerBuilder的标准资料型态例如String、Long、 Integer、Char等等。 所以这个介面提供了关于每个变数的资讯包括变 数的类型、标记、存取权限Public、Private和Protected、变数值或参数 存取方式例如Call by Value或是Reference。 IPB_Arguments这个介面可以让使用者在PowerBuilder VM和「PB Extension」间传递参数。 IPBX_NonVisualObject和IPBX_VisualObject这两介面很意思因为它 们可以在C程式中实作出来而且是放在PB Extension里面你在 PowerBuilder中就可以用PBD的方式看到你实作出来的物件而要写这 些可见或是不可见的物件靠的就是IPBX_NonVisualObject和 IPBX_VisualObject介面。 IPBX_Marshaler这个介面是当你要出一个「PB marshaler extension 」时 一定要实作出IPBX_Marshaler这个介面。 这个介面尤其是你要由 PowerBuilder呼叫Java程式时一定要用到的一个介面。 PBNI提供的Structures PBCallInfo这个Structure可以在开发PBNI程式时让PBNI和 PowerBuilder之间呼叫的函数保持参数和回传值的资讯。 如果要存取在 PBCallInfo中的资讯可以使用IPB_Arguments介面来获得PBCallInfo。 PBArrayInfoPBArrayInfo是一个C的structure这个Structure可以 在阵列中保持一些资讯。 PBNI提供的Globle Function 如果你要写一个PowerBuilder extension的程式说穿了就是用C写一个 DLL档啦这个物件必须要汇出两个Global Functions让这个程式可以「内 嵌」 PowerBuilder VM并且建立实体出来。 下面是PBNI提供的Globle Function PBX_GetDescription PBX_CreateNonVisualObject PBX_CreateVisualObject PBX_InvokeGlobalFunction PBNI提供的Helper classes Helper Classes指的是一些辅助的类别物件PBNI提供像是PBObjectCreator、 PBArrayAccessor和PBEventTrigger等辅助类别透过这些辅助类别物件可使 PBNI在开发上更简单。 PBNI的开发方式 在了解PBNI有那些元素后读着应该也了解到何谓PBNI并且知道PBNI能帮 我们做什么。 在针对不同的目地PBNI也有不同的开发方式常见的PBNI开 发目地为下列四个在后面的部份会祥细的说明PBNI的开发方式为何 建立PB extensions 建立PB marshaler extensions 建立PB visual extensions 内嵌PBVM到C的应用程式中 建立PB extensions步骤 之前有跟各位读者提过PBNI提供了两个对外的方法其中一种就是将C或是 C写好的DLL档案透过PBNI提供的介面来包装成一个PowerBuilder认得的 PBD档案这种方式称之为建立「PB Extensions」。 在开发一个PB Extensions的 程式时我们必须先设想好最后我们要产生的PBD中会有那些物件。 比方 说我现在手头上正在写一个C的程式我希望这个C的程式最后透过PBNI 的帮助产生一个PBD档案而且在这个PBD里面有一个Funtion物件而这 个Function物件会对照于我在C里面写好的Function让我只要呼叫该Function 物件就等于是执行C里的程式。 刚才的设想中开发的步骤如下 1.使用C的开发工具建立一个C专案。 2.在C的程式中汇入PBNI SDK提供给C的相关表头档h档案。 3.在C的程式中透过PBX_GetDescription这个PBNI提供的函数告知 到时后会汇出一个Globle Function。 4.因为要做的是一个Globle Function物件所以在C的程式中透过 PBX_InvokeGlobalFunction这个PBNI提供的函数实作该Function的程 式出来。 5.将开发好的C程式编辑成DLL档。 6.透过PBNI提供的「pbx2pbd90.exe」小工具将这个DLL档案转换为PBD 档。 7.打开PowerBuilder后将这个PBD档加到Library Search Path中。 8.开发相关的PowerBuilder程式并且呼叫这个PBD档的Globle Function。 定义要汇出的物件类别 在上述的步骤中PBX_GetDescription这个PBNI提供的函数是一定要有的因 为这个函数是用来产生相关的类别定义而这个类别定义最后会在将DLL档案 转换成PBD档时跟据你在PBX_GetDescription函数中的定义产生相对应的 PowerBuilder物件。 下面在C的程式最后会产生一个PB的Globle Function物 件这个Globle Function物件名称是GetUserName而它的回传值是String资料 型态 PBXEXPORT LPCTSTR PBXCALL PBX_GetDescription static const TCHAR desc quotglobalfunctions nquot quotfunction string GetUserNamenquot quotend globalfunctions nquot return desc 再举一个例子下面写在C里的PBX_GetDescription函数程式最后会产生一 个PowerBuilder的可视物件「flagext」在这个可视物件中有两个事件为分别 为「onclick」Event和「ondoubleclick」 Evnet在可视物件中还有两个物件 Function 「settextstring txt」和「setflagint flag」 PBXEXPORT LPCTSTR PBXCALL PBX_GetDescription static const TCHAR desc quotclass flagext from usero b j e c tnquot quotevent int onclicknquot quotevent int ondoubleclicknquot quotsubroutine settextstring txtnquot quotsubroutine setflagint flagnquot quotend classnquot return desc 实做类别物件程式码 之前提到的步骤中除了PBX_GetDescription之外我们还会步骤四中看到一个 PBNI提供的Function叫PBX_InvokeGlobalFunction这是因为我们要实作出 Globle Function的程式所以就必须要使用PBX_InvokeGlobalFunction函数相同 的道理如果在PBX_GetDescription中我们准备建立的是一个NVO物件那就 要用PBX_CreateNonVisualObject函数实作出NVO物件的程式如果在 PBX_GetDescription中我们准备建立的是一个可视的PowerBuilder物件那就要 用PBX_CreateVisualObject函数实作出这一个可视物件的程式。 下面是一个在 C中使用PBX_InvokeGlobalFunction来实作出一个Globle Function程式的例 子 PBXEXPORT PBXRESULT PBXCALL PBX_InvokeGlobalFunction IPB_Session pbsession LPCTSTR functionName PBCallInfo ci if strcmp functionName quotgetusernamequot 0 CWinAPI WinAPI new CWinAPI pbsession WinAPI-gtPBNIGetUserName ci if WinAPI NULL delete WinAPI return PBX_OK return PBX_E_NO_SUCH_CLASS 在上面的程式码中读者可以发现程式PB Extension和PB的核心PBVM的沟 通是透过IPB_Session这个指标变数来保持C和PowerBuilder程式的连结而 在PBNI和PowerBuilder之间呼叫的函数保持参数和回传值的资讯就是透过之前 介绍的PBCallInfo这个指标结构来保存下面是PBVM和PB Extension之间的关 系示意图 此主题相关图片如下2.jpg 下面是完整的程式码这个程式码中在pbniwinapi.cpp程式实作出类别 「CWinAPI」在这个Class中有一个PBNIGetUserName函数会透过Windows 作业系统的API取得电脑的使用者名称而main.cpp中会汇出一个PB Globle Function叫「GetUserName」 pbniwinapi.cpp include ltWINDOWS.Hgt include ltstdio.hgt include quotPBNIWINAPI.hquot CWinAPI::CWinAPI IPB_Session pSession : m_pSession pSession CWinAPI::CWinAPIvoid void CWinAPI::PBNIGetUserName PBCallInfo ci LPTSTR lpszSystemInfo DWORD cchBuff 256 TCHAR tchBuffer1024 lpszSystemInfo tchBuffer GetUserName lpszSystemInfo ampcchBuff ci-gtreturnValue-gtSetString lpszSystemInfo void CWinAPI::Destroy delete this main.cpp include ltwindows.hgt include ltpbext.hgt include quotpbniwinapi.hquot BOOL APIENTRY DllMain HANDLE hModule DWORD reasonForCall LPVOID lpReserved switch reasonForCall case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break return TRUE PBXEXPORT LPCTSTR PBXCALL PBX_GetDescription static const TCHAR desc quotglobalfunctions nquot quotfunction string GetUserNamenquot quotend globalfunctions nquot return desc PBXEXPORT PBXRESULT PBXCALL PBX_InvokeGlobalFunction IPB_Session pbsession LPCTSTR functionName PBCallInfo ci if strcmp functionName quotgetusernamequot 0 CWinAPI WinAPI new CWinAPI pbsession WinAPI-gtPBNIGetUserName ci if WinAPI NULL delete WinAPI return PBX_OK return PBX_E_NO_SUCH_CLASS 产生PowerBuilder延伸物件 在上面的C程式完成后便可以编辑一个DLL档案可是这个DLL档案并不 是要让PowerBuilder直接拿来用因为这样子一来就又回到使用外部函数的做 法比较好的方式是要产生PB Extension也就是说把这个DLL「再包一层」 用一个PBD帮这个DLL档案做一个PowerBuilder看的懂的外皮然后让 PowerBuilder透过PBD来「认识」你写好的DLL程式。 在PowerBuilder9安装目录下Sybase9PowerBuilder 9.0SDKPBNI你会发 现有一个叫「pbx2pbd90.exe」的档案如果要帮DLL再包一层PBD档案必须 透过pbx2pbd90.exe这一个档案它的语法如下 pbx2pbd90 your.pbd your.dll 比方说有一个DLL档案叫「pbniwinapi.dll」要把这个档案转成PBD档就可 以这样子下 pbx2pbd90 pbniwinapi.pbd pbniwinapi.dll 如此一来它会产生「pbniwinapi.pbd」档并且根据你原先写在C程式中的 PBX_GetDescription函数内容在这个PBD档案产生出相对应的PowerBuilder 可以认得的物件让开发人员取得该物件后用PowerBuilder原生语法 PowerScript就可以呼叫该物件的函数来做事情。 下图是一个产生PBD档案的示意图 此主题相关图片如下3.jpg PowerBuilder使用PB Extension开发程式 产生好PB Extension后读者一定很好奇两件事第一件事就是我可不可以只要 用产生好的PBD物件而把原来的DLL档案删除答案是不行因为PBD物件 只是一个帮DLL档案产生出来的一个「空壳」借由这个PBD空壳PowerBuilder 才行使用DLL程式第二个问是就是使用PB Extension的步骤为何其实使用 PB Extension很简单只要把它当作是一般的PowerBuilder程式物件来用就可以 了下面是它的使用步骤 1.将产生好的.PBD档案加到你的PowerScript Target也就是把这个PBD档 案加到Library Search Path中。 2.将PB extension DLL档案拷贝到开发程式目录下面 3.使用PowreScript语法呼叫物件的函数 假设现在有一个PB Extension档案加到Library Search Path中在这个PBD里面 有一个NVO物件叫「SimpleExt」在该物件有一个「hello」函数在 PowerBuilder的程式中就会这样子写 SimpleExt ext ext create SimpleExt String str Str ext.hello “Hello what’s your name ” Messagebox “hello ” str 下面是这次呼叫PB Extension程式的流程示意图 此主题相关图片如下4.jpg 内嵌PBVM 在一开始的时后提到PBNI提供了两扇对外的门户一个是可以将C或C的 程式转成PB Extensions也就是转成PBD的方式另一个对外的门户是可以在 C程式中「内嵌PBVM」。 关于第一种方法在上面介绍过了而接下来就是要 介绍第二种对外的门户内嵌PBVM。 相信读者在开发其他的语言程式时一定时常会有一个希望「啊如果我的Java 程式可以使用DataWindow物件就好了。 」 或是「上次的专案我已经用 PowerBuilder开发好一些模组在这次的C专案中真不想再写一次。 」 如果读者有这种需求这时后最好的方式就是使用「内嵌PBVM」的作法 透过这个PBNI的技术C的程式也可以顺利的呼叫PowerBuilder开发好的物 件具体的开发方式为 1.在C程式中载入PBVM。 2.在C程式中利用IPB_VM介面来取得C和PB的连结。 3.建立该PBL或是PBD的Library Session其实也是透过IPB_Session介 面。 4.在C里面建立这个NVO物件的实体。 5.呼叫这个NVO物件的Function。 举例来说我有一个「trypbni.pbl」在这个PBL档案中有一个NVO物件叫作 「n_ben」物件在该物件中有一个foo函数现在在开发一个C的程式时 就可以把PBVM给内嵌到C程式中并且在C程式呼叫这个n_ben.foo函 数相关的的部份程式码如下 trypbni.cpp 1. int mainint argc char argv 2. 3. HINSTANCE hinst LoadLibraryquotpbvm90.dllquot 4. P_PB_GetVM getvm P_PB_GetVMGetProcAddresshinst quotPB_GetVMquot 5. IPB_VM vm NULL 6. getvmampvm 7. static const char liblist quottrypbni.pblquot 8. IPB_Session session NULL 9. vm-gtCreateSessionquottrypbniquot liblist 1 ampsession 10. pbgroup group session-gtFindGroupquotn_benquot pbgroup_usero b j e c t 11. pbclass clz session-gtFindClassgroup quotn_benquot 12. pbmethodID mid session-gtGetMethodIDclz quotfooquot PBRT_FUNCTION quotISquot 13. pbobject obj session-gtNewObjectclz 14. PBCallInfo ci 15. session-gtInitCallInfoclz mid ampci 16. ci.pArgs-gtGetAt0-gtSetStringquotCalling PowerScript from Cquot 17. session-gtInvokeObjectFunctionobj mid ampci 18. session-gtFreeCallInfoampci 19. session-gtRelease 20. FreeLibraryhinst 21. return 0 22. 读者可以在第三行发现在C要「内嵌」PBVM会使用LoadLibrary这个函数 把pbvm90.dll加到C程式中在第七行指定要使用trypbni.pbl在第十一行找 到n_ben物件在第十二行呼叫n_ben.foo函数。 在完成上面的程式后就可以 把这支C程式编辑变成一支可以呼叫PowerBuilder物件的程式。 如果是要在Java中呼叫PowerBuilder. 下载我要获得 会员登录 【设为主页】【加入收藏】【打印本文】【回到顶部】【关闭此页】 相关文章 ·LINUX与UNIX SHELL编程指南 ·Unix哲学基础 ·LINUX与UNIX_SHELL编程指南 ·《UNIX环境高级编程》的笔记——wai ·UNIX环境下C语言编程规范 ·Unix多线程编程与网络编程(解密) ·Unix连接 ·UNIX操作系统简介 ·linux与unix_shel编程经典教 最新文件 特别推荐