前往Shuct.Net首页

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

关于PowerBuilder的搜索

--> tuxedo_PowerBuilder.html Oracle Country Country Communities I am a... I want to... Welcome Account Sign Out Sign In/Register Help Products Solutions Downloads Store Support Training Partners About OTN Oracle Technology Network Articles Enterprise Architecture Application Development Framework Application Express Big Data Business Intelligence Cloud Computing Communications Database Performance & Availability Data Warehousing .NET Dynamic Scripting Languages Embedded Digital Experience Enterprise Architecture Enterprise Management Identity & Security Java Linux Service-Oriented Architecture Solaris SQL & PL/SQL Systems - All Articles Virtualization Using Tuxedo with PowerBuilderby Paco Gómez 02/22/2005 AbstractThis article describes how to use BEA Tuxedo with PowerBuilder. The versions covered are BEA Tuxedo 8.1 and Sybase PowerBuilder 10.0. While Tuxedo and PowerBuilder are veteran products, the upgrade of legacy middleware to SOA is renewing the interest in integrating Tuxedo with PowerBuilder and other 4GL tools.For example, DCE/RPC-based client/server applications can be easily upgraded using Tuxedo ATMI as the communication layer. The business logic C server code and the presentation PowerBuilder client code doesn't need to be changed; only the communication interface must be changed. This article describes how this can be accomplished.The ExampleTo illustrate how to integrate PowerBuilder (PB) with Tuxedo, a simple example is provided. The example consists of a PB client application (pbclient) that calls a Tuxedo ATMI server (txserver). The client application uses an FML buffer to send a string and a long number to the server. The server converts the string to uppercase, calculates a random number n between 1 and the received number, and sends the converted string back to the client in n records inside the outbound FML buffer. The example shows how to pass different data types between PB and Tuxedo as well as how to deal with dynamic structures in PB representing variable length data received from Tuxedo.The source code of the Tuxedo server and the PowerBuilder client applications are included with this article.ArchitectureThe architecture of our example scenario is as follows. The PB client uses the Tuxedo Workstation (WS) component to invoke the Tuxedo server through the ATMI API. The PB client makes calls to the ATMI and FML32 APIs declared in PB as external functions. The calls are dynamically linked to Tuxedo/WS DLL libraries (LIBWSC.DLL and LIBFML32.DLL) at runtime. Figure 1 is a high-level diagram of the example. Figure 1: The architecture describing the example scenario The Tuxedo server (txserver) is a standard ATMI server using FML32 buffers for inbound and outbound data.Tuxedo Functions DeclarationTo use the ATMI and FML32 functions in PB, these need to be declared as Global External Functions, as shown in Figure 2. Figure 2: Declared Global External Functions in PowerBuilder It is very important to declare these functions with the correct signature to avoid compilation or runtime errors. The data types of the arguments must correspond with the data types as declared in the ATMI and FML32 functions definitions. Here are some typical correspondences and rules: C “int” and “long” numbers correspond to “Long” data type in PB. C pointers (to any type) are represented as “Long” data in PB. Reference arguments must be declared with the “ref” keyword in PB. When passing a string to an external function by reference, all memory management is done in PB. The string variable must be long enough to hold the returned value. If the string uses ANSI encoding, the ALIAS must be qualified with the “ansi” keyword. The PowerBuilder help documentation provides additional details about other data types.Here is the complete listing of external function declaration: FUNCTION int tpinit(long tpinfobuf) LIBRARY "LIBWSC.DLL" FUNCTION int gettperrno() LIBRARY "LIBWSC.DLL" FUNCTION string tpsterror(int errnum) LIBRARY "LIBWSC.DLL" FUNCTION int tpterm() LIBRARY "LIBWSC.DLL" //int tpcall(char *svc, char *idata, long ilen, char **odata, long *olen, long flags) FUNCTION int tpcall(string svc, long idata, long ilen, ref long odata, ref long olen, long flags) LIBRARY "LIBWSC.DLL" ALIAS FOR "tpcall;ansi" //char * tpalloc(char *type, char *subtype, long size) FUNCTION long tpalloc(string theType, string theSubType, long theSize) LIBRARY "LIBWSC.DLL" ALIAS FOR "tpalloc;ansi" //int Fadd32(FBFR32 *fbfr, FLDID32 fieldid, char *value, FLDLEN32 len) FUNCTION int Fadd32String(long fbfr, long fieldid, ref string value, long len) LIBRARY "LIBFML32.DLL" ALIAS FOR "Fadd32;ansi" FUNCTION int Fadd32Long(long fbfr, long fieldid, ref long value, long len) LIBRARY "LIBFML32.DLL" ALIAS FOR "Fadd32;ansi" //int Fget32(FBFR32 *fbfr, FLDID32 fieldid, FLDOCC32 oc, char *loc, FLDLEN32 *maxlen) FUNCTION int Fget32String(long fbfr, long fieldid, long oc, ref string loc, ref long maxlen) LIBRARY "LIBFML32.DLL" ALIAS FOR "Fget32;ansi" FUNCTION int Fget32Long(long fbfr, long fieldid, long oc, ref long loc, ref long maxlen) LIBRARY "LIBFML32.DLL" ALIAS FOR "Fget32;ansi" //void tpfree(char *ptr) SUBROUTINE tpfree(long buffer) LIBRARY "LIBWSC.DLL" Declaring Aliases for FML32 CallsThe FML32 Fadd32 and Fget32 functions declare as pointer to a char ( char *) the argument with the value to add or get to and from the buffer. While this is valid in C, PowerBuilder will throw a compilation error if the function argument is declared with the ref long data type and then, for example, is called with a string as the actual parameter. To overcome this issue we can take advantage of the PowerBuilder feature of declaring aliases for external functions. With this PB feature, we can declare an external function with a name that doesn’t need to be the same as the name exported by the DLL. In fact, we can create different aliases for the same function. Each alias declared will have a different name and a different signature to avoid compilation errors, but they all refer to the same DLL function. At runtime, PB will pass the data back and forth to the FML32 function in the right format.In our example, Fadd32 has two aliases, Fadd32String and Fadd32Long. The original char * value argument is declared as “ref string” in the first alias and as ref long in the second alias. When adding a string or a long value to the FML32 buffer, use one or the other to avoid any compilation or runtime issues. Calling Tuxedo FunctionsThe following program listing corresponds to the clicked action of the call txserver button in the PowerBuilder client application. The code shows how to work with the FML32 buffer and how to call the server with the tpcall function. For convenience, the constants representing FML32 fields ( IN_STR, IN_LONG, OUT_LONG, and OUT_STR) are explicitly declared in the Global Variables section in PB, with the values generated by the mkfldhdr32 command. int result, n long fbuf, input_long, output_long, max_str_len, cnt, len string input_str, output_str string string_array[] max_str_len = 64 * 1024 output_str = space(max_str_len) input_str = sle_1.text input_long = long(sle_2.text) //this call could go in a global initialization result = tpinit(0) fbuf = tpalloc("FML32", "", 1024) result = Fadd32String(fbuf, IN_STR, input_str, 0) result = Fadd32Long(fbuf, IN_LONG, input_long, 0) result = tpcall("txserver", fbuf, 0, fbuf, len, 0) result = Fget32Long(fbuf, OUT_LONG, 0, output_long, len) messages.text = "" for n = 1 to output_long len = max_str_len result = Fget32String(fbuf, OUT_STR, (n - 1), output_str, len) string_array[n] = output_str messages.text = messages.text + string(n) + ": [" + string_array[n] + "] :: " next tpfree(fbuf) //this call could go in a global finalization result = tpterm() This code also illustrates how Tuxedo and PowerBuilder cooperate to handle arbitrary length data, like strings or array of strings. As mentioned earlier, PowerBuilder has to manage the memory used by a string, therefore the string has to be initialized in PowerBuilder with enough space to store the data retrieved from the FML32 buffer with the Fget32String function. In the code, the string is initialized with 64k blank spaces. The string is then passed by reference to the Fget32String function. max_str_len = 64 * 1024 output_str = space(max_str_len) ... Len = max_str_len result = Fget32String(fbuf, OUT_STR, (n - 1), output_str, len) PB supports arrays of variable size. This data structure is appropriate to store an arbitrary number of fields of the same type received in a FML32 buffer. We just have to let PB handle the dynamic grow of the array, as in the example: for n = 1 to output_long len = max_str_len result = Fget32String(fbuf, OUT_STR, (n - 1), output_str, len) string_array[n] = output_str next This screenshot shows the PB client application running: Figure 3. The PB client application running Before running the client application, the following environment variables need to be set: WSNADDR - the network address of the WSL to contact, for example: WSNADDR=//10.1.1.25:4444 TUXDIR - the Tuxedo installation directory PATH - add %TUXDIR%\bin to the PATH variable ConclusionThis article describes the main issues to consider when using Tuxedo with PowerBuilder. Tuxedo ATMI and FML APIs are declared as external functions, dynamically linked at runtime. PowerBuilder integrates seamlessly with Tuxedo when the functions are declared with the right signature and the dynamic memory is managed by PowerBuilder. Enjoy working with Tuxedo and PowerBuilder; the author certainly had a lot of fun playing around with these two veterans!References Sybase PowerBuilder 10.0 Documentation Paco Gómez is senior principal systems engineer at BEA Systems where he has been helping customers architecting solutions since 1999. E-mail this page Printer View Oracle Cloud Learn About Oracle Cloud Get a Free Trial Learn About PaaS Learn About SaaS Learn About IaaS Java Learn About Java Download Java for Consumers Download Java for Developers Java Resources for Developers Java Cloud Service Java Magazine Customers and Events Explore and Read Customer Stories All Oracle Events Oracle OpenWorld JavaOne Communities Blogs Discussion Forums Wikis Oracle ACEs User Groups Social Media Channels Services and Store Log In to My Oracle Support Training and Certification Become a Partner Find a Partner Solution Purchase from the Oracle Store Contact and Chat Phone: +1.800.633.0738 Global Contacts Oracle Support Partner Support E-Mail: help@oracle.com --> Hardware and Software, Engineered to Work Together Subscribe Careers Contact Us Site Maps Legal Notices Terms of Use Privacy Oracle Mobile Facebook LinkedIn Twitter Google+ YouTube Oracle RSS Feed