Jump to content
RSG

Can multiple packages (.bpl) access Python via PythonEngine?

Recommended Posts

My app consists of a main VCL-based app and a number of plugins implemented as .bpl packages. I'd like to incorporate Python using P4D, but I'm having problems. My first attempts work fine in the main app, but I cannot get the bpl's to work. In effect, my main app loads the Python .dll, runs some Python code, then loads the .bpl packages; these packages, however, can't seem to access the Python .dll, as GetPythonEngine thinks the global variable gPythonEngine is nil. My guess is that this is explained because gPythonEngine belongs to the app, and is not visible in the .bpl.

 

I tried loading the Python .dll in both the app and the .bpl, but that doesn't seem to work in a different way when I try to load a Python module. I first try to add a folder to the Python path using the following, abd I get a EPyAttributeError with the message "module 'sys' has no attribute 'Path'.

 

      if not Boolean(SysModule.Path.Contains(folder)) then
        begin
          SysModule.Path.Insert(0, folder);
        end;
 

My guess is that I am not going to be able to use P4D from both the main app and several .bpl (i.e. DLLs) simultaneously. It seems there are a few reasons why, but I'm not certain if I understand exactly the limitations.

 

1. It appears that the Python DLL really only supports one instantiation per process. It isn't entirely clear if this is a DLL restriction or due to the Python DLL's design itself. Is this true absolutely?

2. Even if I could "share" the Python environment created when loading the DLL, I'm likely to run into problems because some functions use that global; for example, the SysModule functions don't provide a means to provide the pointer to the Python environment, but rather access that global directly. Is this correct?

3. Because I use certain .bpls as plug-ins, I can't readily get rid of the .bpls and go to a monolithic architecture, so it seems my only option might be to write another .bpl that encapsulates all the P4D/Python.dll stuff in it, and provides routines for other .bpls and the main app to give access to the Python environment that way. Other than being a bit more work, this does have some nice characteristics, such as hiding all the P4D details in one place, and it formalizes the notion of the Python environment (e.g. when it starts, who "owns" it, and its global nature). This could really work well for my application, as its use of Python is, by domain design, serialized naturally, and benefits from the persistent state from call to call. But before I go down that road, does this even make sense? 

Share this post


Link to post

Put the python code in a bpl and have everything access it that way. But I guess you'll all be sharing the same python interpreter. I think that's essentially the python design. 

Share this post


Link to post

Thanks, David, for the confirmation - that is exactly what I've done since posting the above, and it seems to work as expected.

 

I believe you are right about "sharing the same Python interpreter. For my purposes, this is actually a good thing, as my app essentially serializes access to Python, and I need to maintain some state there - specifically, an Octave environment! So even though this solution might at first seem a pain, it is actually a good thing - for me, anyway!

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×