The art of solving performance problems

Enterprise Application Performance

Subscribe to Enterprise Application Performance: eMailAlertsEmail Alerts newslettersWeekly Newsletters
Get Enterprise Application Performance: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn

Application Performance Authors: Elizabeth White, Jason Bloomberg, APM Blog, AppDynamics Blog, John Worthington

Related Topics: Enterprise Architecture, Enterprise Application Performance


Using PowerBuilder Assemblies in .NET

Reusing PowerBuilder logic in .NET projects

PBDJ Feature Story

There's a lot of "legacy" PowerBuilder code that you might want to access from .NET applications or perhaps PowerBuilder has some superior functionality that you would like to make use of in a .NET application. Think about how easy it would be to create a report in PowerBuilder with a DataWindow. Of course, PB can provide functionality through Web Services (see my article "Prognos with DataWindow.NET 2.0 and PowerBuilder 11 Web Services" in PBDJ some time ago) but this has its limitations.

In the article "PowerBuilder 11's .NET Interoperability" in PBDJ, John Strano showed briefly how to use a PowerBuilder assembly in .NET. This article demonstates how to create a PowerBuilder assembly and elaborates on how to reuse this assembly in C# projects. First, I will start with a simple console application, then go over to an ASP.NET page and finish with a Silverlight application.

The PowerBuilder NVO
The simple sample is a calculator NVO that includes the four basic mathematical operations: addition, subtraction, multiplication and division. I first created a new .NET assembly target in a workspace. In the wizard I named it calculator instead of the defaults and did not add additional libraries to the library list. I chose catsoft as a namespace but named the DLL calculator.dll. There was no need to add resource files and Win32 DLLs for the sample project. Before finishing the wizard, I named the setup file calculatorsetup.

At first I added the functions of_Add, of_Subtract, of_Multiply and of_Divide. Each of these functions takes two long values as arguments and returns a long value (I know that a division could result in a decimal value but for the sample long is okay). I guess there's no need to provide more details for these functions. After finishing the functions, we're ready to deploy the calculator assembly. To do so, I opened the project painter and switched to the objects tab. This page defines the interface between the PowerBuilder and the .NET world. In PowerBuilder we use some PB naming conventions and have the calculator object called n_calculator with methods beginning with of_. We changed this to a more C#-looking style by removing n_ from the class name, of_ from the function names, and making the first letter of each function name upper case. We can add a description to the class and each function to make the usage in .NET simpler. As there's no need to change any other settings in the wizard, we just deployed the project.

PowerBuilder Assembly in Console
The next part of the programming takes place in Microsoft Visual Studio. I created a new C# Windows Console project that uses the .NET Framework 2.0. To make use of the calculator I had to add the assembly to the project, which I did by right-clicking on the reference folder and choosing Add Reference. This allowed me to browse for the PowerBuilder assembly. After adding the assembly, click on it once to show the properties. One option is Copy Local. If this is set to True, the PowerBuilder assembly will be copied to the output directory of the C# project. This is the default and one thing to remember. When you update the PowerBuilder DLL but don't build the C# project, the DLL in the C# project is still the old one.

By double-clicking on the assembly, I opened the Object Browser and inspected the PowerBuilder object (see Figure 1). The assembly name is calculator, the namespace is catsoft, and the calculator object is called calculator. When I highlighted the function Add, the arguments and the additional description were visible.

The console application is very simple. It takes three arguments that are entered by ReadLine and calls, depending of the operator, the appropriate function in the calendar assembly. The source code is available in Listing 1. (Listings 1 - 3 can be downloaded here.) Note that the whole application doesn't do any error checking. There are neither checks for valid arguments nor operators nor checks to prevent a division by zero.

PB Assembly in ASP.NET
Using the PowerBuilder assembly in an ASP.NET project is quite simple. I created a new C# ASP.NET project and added the calculator assembly as a reference as I did in the previous sample. On the default.aspx page I added two asp:TextBoxes for entering the arguments: an asp:DrowDownList to choose the operator, an asp:Button called calculate, and an asp:Label to display the result. The C# code in the back end is similar to the code in the console sample. The whole project is visible in Listings 2 and 3. There is no fancy formatting or div usage. The page uses a table for entering and displaying data.

PowerBuilder Assembly in Silverlight
You can't add an assembly that isn't compiled against Silverlight to a Silverlight project. This is because the CLR from the desktop and Silverlight are different. However, there's a simple solution. A Silverlight solution consists of two projects one of which is the actual Silverlight application; the second is the website that hosts the pages with the Silverlight plug-in. The website hosting the pages with the Silverlight plug-in can use a non-Silverlight assembly such as the PowerBuilder DLL. It can provide its functionality through Windows Communication Services to the Silverlight plug-in.

At first I created a Silverlight solution in Visual Studio and named it CalculatorSilverlight. In the same process Visual Studio offered to add a project to host this solution. I chose to create a new one that I named CalculatorSilverlight.Web. To this CalculatorSilverlight.Web project I added the calculator PowerBuilder assembly as in the previous samples. I also added a new WCF service to this project by right-clicking on the project name and choosing Add, New Item, and then C# WCF Service, which I called CalculatorService. Visual Studio creates a couple of files, one of which is called CalculatorService.svc.cs. In this file the available operations are defined as OperationContract. For each of the functions in the PowerBuilder assembly I added an OperationContract as listed for the Add function.

public int Add( int arg1, int arg2)
calculator c = new calculator();
return c.Add( arg1, arg2 );

Before switching to the Silverlight project, I defined a fixed port for running the application from the Visual Studio IDE. I did this by right-clicking on the web project, choosing properties, selecting the Web tab and switching from the auto-assign port to the specific port. If we didn't do this, the port would be assigned dynamically and the service wouldn't be found during runtime. After this I built the web project. Now I switched to the Silverlight project, right-clicked on the project name and chose Add Service Reference. In the dialog I chose Discover, Services in the Solution and received a list of services (see Figure 2).

I chose CalculatorServiceReference as a namespace and then saved it. The methods of this service are available in my Silverlight application. In the MainPage.xaml I drew a calculator by adding a grid of five rows and two columns. In this grid I placed TextBoxes, TextBlocks, a ComboBox and a button named btnCalculate (see Figure 3). By double-clicking on the button I added the event btnCalculate_Click to the project. On the visual part, all is set.

A Silverlight application communicates asynchronously with the server. This means that after calling an operation, the services don't return the result immediately. However, when the calculation is done, an event in our Silverlight plug-in is fired. We have to catch these events by adding them dynamically when the page is loaded. I defined the variable calc as CalculatorServiceClient in the MainPage class and used the following code in the Page_Loaded event to add the required events (only the add function is shown):

calc = new CalculatorServiceClient();
calc.AddCompleted +=new

Whereas the add event looked like this:

void calc_AddCompleted(object sender, AddCompletedEventArgs e)
result.Text = e.Result.ToString();

What's left is calling the calculation from the btnCalculate_click script. The script takes the values the user enters and calls the appropriate calculation. The call of the add function is listed.

calc.AddAsync(arg1, arg2);

You can download the source code of all the samples in this article from the download section of our website.

To make use of a PowerBuilder.NET DLL, deploy the PowerBuilder runtime files. Use the PowerBuilder Runtime Packager and choose PowerBuilder.NET components. This will create an Installer file that you can use on the target computer. In addition to the PowerBuilder DLL, you have to distribute the associated PBD as well. To protect your WCF services so only your Silverlight application can access it, make use of the ClientAccessPolicy.xml file. This file defines who can access the service (for more details visit MSDN:

Creating a .NET assembly from PowerBuilder is a powerful way to provide business logic to .NET applications. Starting with PowerBuilder 12 the distributed assemblies will be fully managed PowerBuilder runtimes that should allow the usage of PowerBuilder.NET code in hosted environments without having to install any additional DLLs.

More Stories By Arthur Hefti

Arthur Hefti is CEO of CATsoft Development GmbH in Zurich. He has been working with PowerBuilder since version 3 and taught dozens of PowerBuilder training classes. He and his team create custom-made client/server and Web applications using XML, Web Services, and encryption.

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.