1. Tobja Franz
  2. PowerBuilder
  3. Wednesday, 13 January 2021 17:37 PM UTC

Hello All,

I'm working my way through the PBNI Programmers Guide, as our company could benefit from some of the PBNI's functionality for testing purposes - notably the PBNI's capability to create and manipulate objects dynamically.

I was particularly interested in the possibility of loading the pbvm170.dll into a c++ application and then start a PB-GUI-Application from there. Thus the first thing I did was to carefully replicate the one example given in the programmers guide under "Calling Powerbuilder from c++", which includes loading the pbvm170.dll with loadlibrary, getting a pointer to the IPB_VM-Interface, creating a session, and importantly, having a message loop running where the session's function processPBMessage is called.

The example worked out fine on first sight, with the application's windows appearing on the screen, able to take user input. But a runtime error (Null object reference) occured every time a newly opened window (opened via openwithparm with some Powerobject parameter) tried to read a property from the PowerObjectParm of the Message Object . The message.PowerObjectParm was an invalid object in that case. 

Does someone know why that is and how I could fix it? I have attached a zip file containing 1) a simple PB-Project whose target Application does nothing but open a window with a parameter via openwithparm, where this window then tries to read a property of the message.PowerObjectParm and 2) a c++ File that follows the required steps to start the Application. With this setup, I get the mentioned runtime error.

I use Powerbuilder Version 2017 R3 Build 1880.

Thanks for any advice!

Attachments (1)
References
  1. https://docs.appeon.com/pb2019r2/native_interface_programmers_guide_and_reference/ch05.html
John Fauss Accepted Answer Pending Moderation
  1. Wednesday, 13 January 2021 19:49 PM UTC
  2. PowerBuilder
  3. # 1

Greetings, Tobja -

Let me be clear: I'm NOT a PBNI expert. Ha! Far from it. But I have created a DLL/PBX in C++ using PBNI and I've waded through some, not all, of the documentation.

Every PB application is, of course, heavily dependent on the PowerBuilder Virtual Machine (PBVM). PBNI provides a means for 1) creating PB extension in C++ that can be called from a PowerBuilder application (what I've done in the past), and 2) using some PB functionality from a C++ application. I don't believe it was designed to run an entire PB application, which is what I think you are attempting to accomplish.

When a PB app starts, the Application Object is the starting point. It asks the PBVM to create the application's global variables and global objects, such as SQLCA and, yes, the Message object, among others, before the Open event fires and the application "takes off".

When a C++ application is in charge, I may be wrong, but I doubt if anything close to that occurs just because the application establishes hooks into the PBVM in order to access PB objects such as windows, NVO's, structures or global functions. So it doesn't really surprise me that there is no Message object in the scenario you have described.

If your goal is to have the C++ application ask the PBVM to run a PB application, you may have to emulate the functionality of the application object or see if you can make the PBVM instantiate and utilize the application object contained in the PB application.

HTH

Regards, John

Comment
  1. John Fauss
  2. Thursday, 14 January 2021 14:52 PM UTC
Thank you, Arnd, for letting me know about the RunApplication method of the IPB_VM interface in PBNI. Obviously I was not aware of this method. Much appreciated!
  1. Helpful
There are no comments made yet.
Tobja Franz Accepted Answer Pending Moderation
  1. Thursday, 14 January 2021 16:32 PM UTC
  2. PowerBuilder
  3. # 2

Thanks for your quick reply John! Very much appreciated.

Yes, as Arnd Schmidt pointed out in a comment, there is also the RunApplication method, which is, in my understanding, the second of two possibilities we are offered for starting the PB-Application. The first one being the one that I used in the attached example, which is, after having created an instance of the IPB_Session Interface, using the IPB_Session's method NewObject to create an instance of the Application object, and then triggering the open event of that instantiated object.

The reason I thought this approach is going to work, is that the documentation states so:

"[...]the application runs from C++ as it does in PowerBuilder"

And the documentation uses that very approach. So I guess either I did something wrong or then it is actually not the case that "the application runs from C++ as it does in PowerBuilder"...

Concerning the RunApplication method, I did try this approach as well, but ran into other kinds of problems, namely that this function does not return until the application being run is closed; So having my message loop in the same thread that also calls RunApplication resulted in no message being processed at all, i.e. the application starting without any windows showing up.

I actually came quite far when I used a std::thread object to call the RunApplication method in a second thread - The PB-App started, windows showed up, even the ones that read from the Message object. But then this meant that I had to use the same instance of an IPB_Session object in two different threads, which I guess explains all of the access violation exceptions that I ran into sooner or later in every trial. (Note that I have no idea of what I'm doing or talking about when it comes to threads, let alone sharing variables between them!)

 

Comment
  1. John Fauss
  2. Thursday, 14 January 2021 19:03 PM UTC
I'm sorry I am not able to be more helpful, Tobja. My impression is that PBNI is not widely utilized, so it may be difficult to find someone active in the Appeon Community that knows enough to help you. However, I do know there are a few PB developers active in the Community that have some PBNI experience. Hopefully one or more of them will reach out to you.

Just an idea for your consideration: You might look into purchasing a Premium Support ticket. If it were me I would first get some assurance from within Appeon that there would be someone available with the knowledge and experience to assist you before spending the money, but it might be worth it. I'd give your question here some additional time, however.

Good luck!
  1. Helpful
  1. Chris Pollach @Appeon
  2. Thursday, 14 January 2021 19:12 PM UTC
Hi Guys;

FWIW: I would ask Roland at TopWiz as some of his free code examples and/or products use the PBNI feature. HTH

Regards ... Chris
  1. Helpful
There are no comments made yet.
Roland Smith Accepted Answer Pending Moderation
  1. Thursday, 14 January 2021 19:37 PM UTC
  2. PowerBuilder
  3. # 3

One of my PBNI projects has the C++ code instantiating a PB NVO and calling functions within it. Some of the functions open windows.

If you are starting a complex PB app from C++, why not just run the EXE?

Comment
  1. Tobja Franz
  2. Monday, 18 January 2021 06:38 AM UTC
Thanks for your reply Roland.

When I run the EXE, I don't have an IPB_Session at my disposal...The motivation behind this experiment was testing - Some testing code could be built upon the features of the PBNI (like triggering some clicked event on a window, then setting some items in a datawindow and then triggering the clicked event of a button). What felt appealing about using the PBNI to start the application was that the testing code (built upon the PBNI) could be completely seperated from the PB-Application-Code. In other words, I can do some testing on a PB-Application without having to modify a single line of code of that PB-Application (Otherwise, I have to make the PB-Applicatoin start its own test, e.g by instantiating a PBNI-Extension which then does the test)
  1. Helpful
There are no comments made yet.
Roland Smith Accepted Answer Pending Moderation
  1. Tuesday, 19 January 2021 15:37 PM UTC
  2. PowerBuilder
  3. # 4

Here is an example of an EXE that instantiates an object and calls a function:

https://www.topwizprogramming.com/downloads/pbni_console.zip

Things to note:

Visual Studio 2017

The PB code is 10.5 but can easily be migrated. In the C code change the LoadLibrary function to use the correct vm.

The function being called has an array argument so you get to see how that is done.

The exe is a console app so start a command prompt window and run the exe from there.

 

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.