on 07-15-2013 9:03 PM
I have a C# assembly that is calling a PowerBuilder.NET(12.1 Build 7217) assembly. The PowerBuilder source code is contained below, you can see it is a rather simple true/false evaluation of a string.
When the PB.NET assembly is called by a Window in C#, it returns the expected result of "true". When the same code is called by a C# assembly, the code returns "", or an empty string.
I have managed to narrow the problem down to the DataStore interactions in the PB.NET assembly. If the PB.NET assembly is called from another assembly, the DataStore always has 0 rows and contains only empty strings. Has anyone seen or dealt with this before?
// Create instance of Datastore
ldsExpression = CREATE DataStore
// Set data object
ldsExpression.DataObject = "d_condition_expression"
//// Setting datawindow expression
lsExpression = 'condition_expression.expression = ~"' + asConditionExpression + '~"'
//// Apply Expression
lsError = ldsExpression.Modify(lsExpression)
IF len(lsError) = 0 THEN ldsExpression.InsertRow(0)
//get the result
lsResult = ldsExpression.GetItemString(1,"condition_expression")
ELSE
lsResult = lsError
END IF
// Destroy instance of ldsExpression
DESTROY(ldsExpression)
RETURN lsResult
Hi Jayme.
The dataobject you assign to the datastore is an external dataobject? If yes where is the settrans or settransobject command? If no what does the ldsExpression.InsertRow(0) command returns?
PS: I use assemblies created with pb.net 12.1 wich are referenced through c# service and have no problem.
Andreas.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
The datastore is not connecting to the database in any way. It is simply being used to evaluate the expression. I have tried other approaches to evaluating the expression as well. (Describe and Evaluate). They all work correctly when called by a window but fail when called by a library.
The insertrow fails when called by a library (returns -1). When it is called by a regular C# window the code returns "true" as expected. Also, the expression I am passing is a simple "1 = 1".
I actually found a work-around for this. It really looks like a PowerBuilder.NET bug that should be addressed in future versions. Calling the PowerBuilder.NET assembly works when called by a Window or a Service but does not work if called by regular DLL assembly.
I found ONE exception to the rule. A PowerBuilder.NET assembly CAN be called by a C# assembly IF it is called by a Window or Service first within the same application. I'm thinking this is because the object remains in memory after the first call and gets reused from there.
Luckily my application consists of a Service that launches several threads contained in a C# assembly. I added this call to the Main method of my Service, and all of the subsequent calls to EvaluateExpression work perfectly regardless of where they are called from.
private static string Evaluate(string expression)
{
var blah = new PowerBuilderAssembly();
return blah.EvaluateExpression(expression);
}
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
var result = Evaluate("1 = 1");
The problem is that all calls to the PB.NET assembly from a C# assembly do not work if there is a datawindow/datastore in the PB.NET assembly. I have tested it dozens of times and have been able to reproduce the issue consistently in a simple test application. No datawindow/datastore code works in that situation.
I enclosed the 2 main files of the test application. Calling Evaluate via the TestLibraryClass does not work unless the PowerBuilder object is instantiated in the Window code itself. The code in TestLibraryClass should be independent of the code contained in the Window, but it's not.
public static class TestLibraryClass
{
public static string Evaluate(string expression)
{
var blah = new PowerBuilderAssembly();
return blah.EvaluateExpression(expression);
}
}
public partial class frmTest : Form
{
public frmTest()
{
InitializeComponent();
}
//This code can be uncommented in order to make all of the calls to the PB.NET assembly work.
//As soon as the PowerBuilder object is created here in the window, all calls to the assembly function as intended.
private void ActuallyWork()
{
//var blah = new PowerBuilderAssembly();
//var resultWindow = blah.EvaluateExpression("(1 = 1)");
//if (resultWindow == "true")
//{
// lblOutputWindow.Text = resultWindow.ToString(CultureInfo.InvariantCulture);
// lblOutputWindow.BackColor = Color.GreenYellow;
//}
//else
//{
// lblOutputWindow.Text = resultWindow.ToString(CultureInfo.InvariantCulture);
// lblOutputWindow.BackColor = Color.Red;
//}
}
private void btnDoStuff_Click(object sender, EventArgs e)
{
var resultFromLibrary = TestLibraryClass.Evaluate("(1 = 1)");
ActuallyWork();
if(resultFromLibrary == "true")
{
lblOutputLibrary.Text = resultFromLibrary.ToString(CultureInfo.InvariantCulture);
lblOutputLibrary.BackColor = Color.GreenYellow;
}
else
{
lblOutputLibrary.Text = "Fail";
lblOutputLibrary.BackColor = Color.Red;
lblOutputWindow.Text = "Fail";
lblOutputWindow.BackColor = Color.Red;
}
}
}
User | Count |
---|---|
71 | |
9 | |
8 | |
6 | |
6 | |
6 | |
6 | |
5 | |
5 | |
4 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.