PowerBuilder 9 Development Technology lecture-PowerBuilder Native Interface (pbni)

Source: Internet
Author: User

PowerBuilder 9 has made a new breakthrough in supporting other development languages. In the past, there were some trade-offs between it and C ++ or Java programs when using PowerBuilder to develop programs, however, there is always no way to provide simple and comprehensive support. Now, with the pbni Technology of PowerBuilder 9, The PowerBuilder program can call Java, or reference the PowerBuilder NVO object function in a C ++ program.

 

In the past, PowerBuilder programs can only access C/C ++ functions through external function calls, however, in PowerBuilder 9.0, a powerful interface called PowerBuilder Native Interface (pbni) was expanded. With pbni development, PowerBuilder developers can not only use object-oriented methods to access C/C ++ functions, in addition, the C/C ++ program can call the objects in PowerBuilder in reverse order to integrate applications. Furthermore, with the combination of JNI and pbni, Java applications can also communicate with Powerbuilder programs in two directions.

 

Before talking about pbni, let's talk about the following three questions:
1. Can developers use PowerBuilder programs to call C or C ++ programs?
2. Can developers use PowerBuilder programs to call some external components such as Java EJB components, Web service components, and Java class programs?
3. Is there a way for developers to use the reverse interface to call programs that have been developed using PowerBuilder using C or C ++?

 
The above three problems can be solved to some extent in the past PowerBuilder, but there are some problems. Traditionally, when using PowerBuilder to develop the above program, if you want to call a C or C ++ program, you can use the method of declaring an external function to use a compiled DLL function,

 

For example:
Function ulong getsyscolor (INT index) Library "user32.dll"
Function Boolean sndplaysounda (string soundname, uint flags) Library "winmm. dll"

But what if it is the following program:
Bool enumwindows (wndenumproc lpenumfunc, lparam, lparam );
This is a big problem, because the so-called "Callback" function technology will be used in this Windows DLL function. The so-called callback function indicates that today there are two objects, A and B, in the program, object a calls the function of object B, and the function of object B calls back other functions of object A. This is called "Callback 」. After PowerBuilder calls the function of C, it is impossible to reference external functions to call the function of PowerBuilder again in this function. In addition to difficulties in using callback functions, external functions also have restrictions on data types, as well as difficulties and problems in using object-oriented development.

Let's talk about how PowerBuilder calls external components. In the past, it was only possible for PowerBuilder to call EJB components through some "com bridge" developed by third-party vendors 」, let the PowerBuilder program call the Java program through the COM component. To allow Java or C ++ to call a PowerBuilder program, the most common method in the past is to package the PowerBuilder program into "OLE Automation server 」. These methods are not really a good solution.
There is no way to directly communicate with Powerbuilder's core "PowerBuilder visual machine". Therefore, in the past, PowerBuilder has been plagued by the inability to communicate with other language programs, this is what we always think is that Powerbuilder is a closed and not open development tool. PowerBuilder 9 has several breakthrough technologies, and pbni is one of them. The so-called pbni (PowerBuilder Native Interface) refers to a native interface provided by PowerBuilder.
(Native Interface). This interface enables PowerBuilder to improve the scalability of other programming languages. For example, this interface can be used to access any type of external applications, or allow other programming languages to access or call a program developed by PowerBuilder. Below is a simple pbni program:

The image of this topic is as follows:

In the preceding figure, pbni provides two interface windows that allow the outside world to interact with the PowerBuilder core (pbvm). The first window refers to the right half of the graph, we can develop "PB extension", and Pb extension will eventually become DLL. Through this technology, C or C ++ DLL programs can be packaged into a "PBD" file, the PBD file can be added to the library search path during development, allowing PowerBuilder to directly access the object functions in PBD, you can treat it as something like PowerBuilder NVO. The second external window refers to the left half of the graph. You can embed PowerBuilder virtual machine into a C ++ application, in the C ++ program, you can directly call the powerscript function.

Pbni Elements

Pbni provides some basic elements through which developers can quickly reference external programming languages. Below are common pbni elements:
Interfaces provided by pbni ):
Ipb_vm: this interface is used to call a program developed by PowerBuilder in C ++ or other programming languages, or to interact with the core "pbvm" of PowerBuilder, or communication and coordination, you can use this interface.
Ipb_session: This is an abstract interface that can be used to define methods such as accessing data in powerscript, creating PowerBuilder objects, and calling powerscript function operations.
Ipb_value: You can think of this interface as the value that represents PowerBuilder. These values can be standard data types of PowerBuilder, such as string, long, integer, and char. Therefore, this interface provides information about each variable, including the variable type, tag, and access permission (public, private, and protected), change the value or parameter access method (such as call by value or reference ).
Ipb_arguments: this interface allows users to pass parameters between PowerBuilder Vm and Pb extension.
Ipbx_nonvisualobject and ipbx_visualobject: These two interfaces are very interesting, because they can be implemented in C ++ programs and placed in Pb extension, in PowerBuilder, you can use PBD to view the objects you have actually created. To write these objects that are visible or invisible, you rely on the ipbx_nonvisualobject and ipbx_visualobject interfaces.
Ipbx_marshaler: this interface is used to implement the ipbx_marshaler interface when you want to generate a "PB marshaler extension. This interface is especially an interface that must be used when you call a Java program by PowerBuilder.

Structures provided by pbni:
Pbcallinfo: This structure allows the function called between pbni and PowerBuilder to maintain the parameter and return value information when developing the pbni program. If you want to access
You can use the ipb_arguments interface to obtain information in pbcallinfo.
Pbarrayinfo: pbarrayinfo is a C ++ structure that maintains some information in the array.
Globle function provided by pbni: If you want to write a PowerBuilder Extension Program (C ++ is used to write a DLL file), this object must export two global functions, this program can "embed" PowerBuilder Vm and create entities. Below is the globle provided by pbni
Function:
Pbx_getdescription ()
Pbx_createnonvisualobject ()
Pbx_createvisualobject ()
Pbx_invokeglobalfunction ()
Helper classes provided by pbni:
Helper classes refers to some auxiliary class objects. pbni provides auxiliary classes such as pbobjectcreator, pbarrayaccessor, and pbeventtrigger. Through these auxiliary class objects, pbni can be easily developed.

Pbni Development Method

After learning about the elements of pbni, I should also understand what pbni is and what pbni can do for us. Pbni has different development methods for different targets. The common pbni development targets are as follows:
Create Pb extensions
Establish Pb extension ALER extensions
Create Pb visual extensions
Embedded pbvm into C ++ applications

 

As mentioned before, pbni provides two external methods, one of which is to write DLL files written in C or C ++, the interface provided by pbni is encapsulated into a PBD file recognized by PowerBuilder. This method is called Pb extensions 」. When developing a PB extensions program, we must first think about it, and finally there will be those objects in the PBD we want to generate. For example, I am writing a C ++ program on hand, and I hope this c ++ program will finally pass through pbni
In this PBD file, there is a funtion object in this PBD, and this function object will be compared to the function I wrote in C ++, let me call this function object and execute the program in C ++. The steps for development are as follows:
1. Use the C ++ development tool to create a C ++ project.
2. In the C ++ program, import the relevant header file (H file) that the pbni SDK provides to C ++ ).
3. In the C ++ program, use the function pbx_getdescription () provided by pbni to export a globle function.
4. Because you want to implement a globle function object, you can use the function provided by pbx_invokeglobalfunction () in the C ++ program to implement the function.
5. Edit the developed C ++ program into a DLL file.
6.parse the pbx2pbd90.exe tool of pbni.pdf and convert the DLL file to the PBD file.
7. Open PowerBuilder and add the PBD file to the library search path.
8. Develop related PowerBuilder programs and call the globle function of this PBD file.

Define the object category to export

In the above steps, the function pbx_getdescription () provided by pbni is required, because this function is used to generate related category definitions, this category definition will eventually generate a corresponding PowerBuilder object when converting the DLL file to the PBD file based on your definition in the pbx_getdescription () function. In the C ++ program, a PB globle function object is generated. The name of this globle function object is GetUserName (), and its return value is a string data type:
Pbxexport lpctstr pbxcall pbx_getdescription ()
{
Static const tchar DESC [] = {
"Globalfunctions/N"
"Function string GetUserName ()/n"
"End globalfunctions/N"
};

Return DESC;
}
For another example, the pbx_getdescription () function program written in C ++ will generate a PowerBuilder visual object "flagext". In this visual object, there are two events: onclick event and ondoubleclick evnet. In the visual object, there are two objects: settext (string txt) and setflag (INT flag) 」:
Pbxexport lpctstr pbxcall pbx_getdescription ()
{
Static const tchar DESC [] = {
"Class flagext from usero B j e c T/N"
"Event int onclick ()/n"
"Event int ondoubleclick ()/n"
"Subroutine settext (string txt)/n"
"Subroutine setflag (INT flag)/n"
"End Class/N"
};
Return DESC;
}

Program code of the Real-Time Category object

In the previous steps, apart from pbx_getdescription (), we will also see a function provided by pbni in Step 4, called pbx_invokeglobalfunction (), because we want to implement the Program for globle function, therefore, you must use the pbx_invokeglobalfunction () function. In the same way, if we are creating an NVO object in pbx_getdescription (), we need to use pbx_createnonvisualobject () the function implements the NVO object program. If we want to create a visual PowerBuilder object in pbx_getdescription (), we need to use pbx_createvisualobject () A function is a program that implements this visual object. The following is an example of using pbx_invokeglobalfunction () in C ++ to implement a globle function program:
Pbxexport pbxresult pbxcall pbx_invokeglobalfunction
(

Ipb_session * pbsession,
Lpctstr functionname,
Pbcallinfo * CI
)
{
If (strcmp (functionname, "GetUserName") = 0)
{
Cwinapi * winapi = new cwinapi (pbsession );
Winapi-> pbnigetusername (CI );
If (winapi! = NULL) delete winapi;
Return pbx_ OK;
};
Return pbx_e_no_such_class;
}
In the code above, the reader can find that the communication between PB extension and Pb core pbvm maintains the connection between C ++ and PowerBuilder programs through the ipb_session indicator variable, the information about function persistence parameters and return values for calls between pbni and PowerBuilder is saved through the pbcallinfo index structure described earlier. The following is the relationship between pbvm and Pb extension:

The image of this topic is as follows:

Below is the complete code, which is in pbniwinapi. CPP program implements the category "cwinapi". In this class, there is a pbnigetusername () function that obtains the user name of the computer through the API of the Windows operating system, while Main. CPP will export a PB globle function called "GetUserName ()」:
Pbniwinapi. cpp
# Include <windows. h>
# Include <stdio. h>
# Include "pbniwinapi. H"
Cwinapi: cwinapi (ipb_session * psession)
: M_psession (psession)
{
}
Cwinapi ::~ Cwinapi (void)
{
}
Void cwinapi: pbnigetusername (
Pbcallinfo * CI)
{
Lptstr lpszsysteminfo;
DWORD cchbuff = 256;
Tchar tchbuffer [1024];
Lpszsysteminfo = tchbuffer;
GetUserName (lpszsysteminfo, & cchbuff );
Ci-> returnvalue-> setstring (lpszsysteminfo );
}
Void cwinapi: Destroy ()
{

Delete this;
}
Main. cpp
# Include <windows. h>
# Include <pbext. h>
# Include "pbniwinapi. H"
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 [] = {
"Globalfunctions/N"
"Function string GetUserName ()/n"
"End globalfunctions/N"
};
Return DESC;
}
Pbxexport pbxresult pbxcall pbx_invokeglobalfunction
(

Ipb_session * pbsession,
Lpctstr functionname,
Pbcallinfo * CI
)
{
If (strcmp (functionname, "GetUserName") = 0)
{
Cwinapi * winapi = new cwinapi (pbsession );
Winapi-> pbnigetusername (CI );
If (winapi! = NULL) delete winapi;
Return pbx_ OK;
};
Return pbx_e_no_such_class;
}

Generate PowerBuilder extension objects

After the preceding C ++ program is completed, you can edit a DLL file. However, this DLL file is not directly used by PowerBuilder, let's go back to using external functions. The better way is to generate Pb extension, that is to say, "package another layer" of this DLL 」, use a PBD to help this DLL file build an external interface that PowerBuilder can understand, and then let PowerBuilder "get to know" Your DLL program through PBD. The file % sybase9 %/PowerBuilder 9.0/SDK/plugin under the powerbuilder9 installation directory has the following syntax:
Pbx2pbd90 your. PBD your. dll
For example, there is a DLL file named "pbniwinapi. dll". To convert this file into a PBD file, you can do this:

Pbx2pbd90 pbniwinapi. PBD pbniwinapi. dll
In this way, it will generate "pbniwinapi. PBD file, and according to the pbx_getdescription () function content you originally wrote in the C ++ program, generate the corresponding PowerBuilder recognizable objects in this PBD file, after developers get the object, they can call the function of the object to do things using PowerBuilder's native syntax powerscript.

Is a PBD file:

The image of this topic is as follows:

PowerBuilder Development Program Using PB Extension

After Pb extension is produced, the reader must be curious about two things. The first thing is, can I delete the original DLL file by using the generated PBD object? The answer is no, because the PBD object is just an empty shell generated by the DLL file. With this PBD shell, PowerBuilder can use the DLL program; the second question is how to use Pb extension? In fact, it is very easy to use Pb extension, as long as it is used as a general PowerBuilder program object.
The following describes how to use it:
1. Add the generated. PBD file to your powerscript target, that is, add the PBD file to the library search path.
2. Copy the Pb extension DLL file to the development program directory.

3. the function that calls an object using the powrescript syntax assumes that there is a PB extension file added to the library search path. In this PBD, there is an NVO object named "simpleext 」, this object has a "hello ()" function, which is written in the PowerBuilder program as follows:
Simpleext ext
EXT = create simpleext
String Str
STR = ext. Hello ("Hello, what's your name? ")
MessageBox ("hello", STR );
The following is the procedure for calling the Pb Extension Program:

The image of this topic is as follows:

At the beginning, we mentioned that pbni provides two external portals. One is to convert C or C ++ programs into Pb extensions, that is, to PBD; another external portal is to "embed pbvm" in the C ++ program 」. The first method has been introduced above, and the next step is to introduce the second external portal with built-in pbvm.

I believe that when developing other language programs, readers will always have a hope: "Ah, if my Java program can use datawindow objects, that would be fine. Or, "I have used PowerBuilder to develop some modules in the last project. I really don't want to write them again in this c ++ project.
If the reader has this requirement, the best way to do this is to use the "embedded pbvm" approach. Through this pbni technology, c ++ programs can also call the objects developed by PowerBuilder smoothly. The specific development method is as follows:
1. Load pbvm in the C ++ program.
2. Use the ipb_vm interface in the C ++ program to obtain the connection between C ++ and Pb.
3. Create the library session of the pbl or PBD (in fact, through the ipb_session interface ).
4. Create the entity of the NVO object in C ++.
5. Call the function of the NVO object.

For example, I have a "trypbni. in this PBL file, there is an NVO object named "n_ben" and there is a FOO () function in the object. Now, when developing a C ++ program, you can embed the pbvm into the C ++ program and call the n_ben.foo () function in the C ++ program. The related code is as follows:
Trypbni. cpp
1. Int main (INT argc, char * argv [])
2 .{
3. hinstance hinst = loadlibrary ("pbvm90.dll ");
4. p_pb_getvm getvm = (p_pb_getvm) getprocaddress (hinst, "pb_getvm ");
5. ipb_vm * Vm = NULL;
6. getvm (& VM );
7. Static const char * liblist [] = {"trypbni. PBL "};
8. ipb_session * session = NULL;
9. VM-> createsession ("trypbni", liblist, 1, & session );
10. pbgroup group = session-> findgroup ("n_ben", pbgroup_usero B j e c t );
11. pbclass clz = session-> findclass (group, "n_ben ");
12. pbmethodid mid = session-> getmethodid (clz, "foo", pbrt_function, "is ");
13. PbO B j e c t OBJ = session-> newobject (clz );
14. pbcallinfo ci;
15. Session-> initcallinfo (clz, mid, & CI );
16. CI. pargs-> getat (0)-> setstring ("calling powerscript from C ++ ");
17. Session-> invokeobjectfunction (OBJ, mid, & CI );
18. Session-> freecallinfo (& CI );

19. Session-> release ();
20. freelibrary (hinst );
21. Return 0;
22 .}
In row 3, you can find that C ++ needs to "embed" pbvm. The loadlibrary () function will be used to add pbvm90.dll to the c ++ program, and trypbni will be used in Row 7. PBL; locate the n_ben object in row 11th; call the n_ben.foo () function in row 12th. After completing the above program, you can edit the C ++ program into a program that can call the PowerBuilder object. What if it is a program that calls PowerBuilder in Java? This is a little more troublesome. To put it simply,
We still need to use the "embedded" pbvm technology, but now there is a problem: theoretically, Java cannot embed PowerBuilder programs. As a result, it is difficult to make Java calls directly or use PowerBuilder programs. In fact, we can use the Java call C ++ program technology "Java JNI" to achieve our goal. That is to say, first, you can use C ++ to write a DLL program called PowerBuilder. Of course, this program must be made using pbni's "embedded" pbvm technology, and then "JNI, let Java call the C ++ DLL program.

Conclusion

PowerBuilder native interface, a powerful new design interface of powerbuilder9, has greatly changed the world's awareness of PowerBuilder. With support from pbni, you can use the functions of the original powerbuilder application, extends to C ++ and Java applications to open a new world and market for these applications. Especially in a competitive environment where information is growing at a high speed, how can an enterprise retain its original investment and make the system more scalable and scalable, with high performance and productivity, I believe that the market leader development tool PowerBuilder has provided the best explanation for this demand.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.