Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

TDynamicDLL improvements and other fixes #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
idanmiara wants to merge 6 commits into pyscripter:master from talos-gis:master

Conversation

@idanmiara
Copy link
Contributor

@idanmiara idanmiara commented Oct 24, 2018

No description provided.

Copy link
Owner

I am not sure what it the problem you are trying to solve. From what I see you set the RegVersion from aDLLName in TPythonEngine.DoOpenDll(const aDllName : String) if UseLastKnownerion is False.
What is the use of that?

PyhthonEngine can be used to work with (a) a registered Python version and (b) a non registered Python version.

In (a) you need to set

  • RegVersion, DLLName and optionally UseLastKnownVersion if a version newer than RegVersion will do.

In (b) you need to :

  • Set DDLPath, RegVersion, DLLName and set UseLastKnownVersion to false.
  • Call SetPythonHome to the appropriate path or set the %PYTHONHOME% environment variable.

Copy link
Owner

Also the implementation GetPythonVersionFromDLLName is platform specific (Windows). In addition there is no need for it to be a member of PythonEngine. It could be a stand-alone function (possibly inside PythonVersions), or a class function.

Copy link
Contributor Author

idanmiara commented Oct 25, 2018 via email

Hi, Thanks for your prompt response. The problem I'm trying to solve is as follows: UserInputDllName := ''; // allow user to input UserInputDllName if he wishes. PyEngine.DllName := UserInputDllName; PyEngine.UseLastKnownVersion := PyEngine.DllName=''; now I want to read PyEngine.RegVersion and I will get a wrong answer in case the user specified the DLL name. I made it platform independent as you suggested. Please note that I GetPythonVersionFromDLLName is a stand alone function and not a method. I put it in PythonEngine.pas and not elsewhere because I use it in PythonEngine.pas and PythonEngine.pas dosen't use any other p4d unit. I didn't see the justification to add a dependency or make a new unit for this function. I'm also pushing my version of LatestPythonVersionFromPath which as far as I can tell is platform independent unlike to PythonVersionFromPath and also allow the use of the uncommon setup of OSGeo4W.
...
On 2018年10月25日 at 04:15, pyscripter ***@***.***> wrote: Also the implementation GetPythonVersionFromDLLName is platform specific (Windows). In addition there is no need for it to be a member of PythonEngine. It could be a stand-alone function (possibly inside PythonVersions), or a class function. — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub <#62 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AZIQrc1vM2HmQQFmGS_NCUmf_S0WSlI_ks5uoRDGgaJpZM4X4OaN> .

Copy link
Owner

I am considering including GetPythonVersionFromDLLName and possibly LatestPythonVersionFromPath but I still do not see the purpose of your other changes:

What is the use of changing DoOpenDLL? You say that

The problem I'm trying to solve is as follows:
UserInputDllName := '';
// allow user to input UserInputDllName if he wishes.
PyEngine.DllName := UserInputDllName;
PyEngine.UseLastKnownVersion := PyEngine.DllName='';
now I want to read PyEngine.RegVersion and I will get a wrong answer in
case the user specified the DLL name.

Why don't you call GetPythonVersionFromDLLName in your code i.e

if UserInputDLLName <> '' then
 PythonEngine.RegVersion := GetPythonVersionFromDLLName(UserInputDLLName);

Also regarding LatestPythonVersionFromPath. This actually deals with a corner case and anyway enen after using this method you still have to call SetPythonHome with a different path than the DLLPath.
The simple solution for QGIS would be to copy the dll and python exe files to the python directory,
By the way a QGIS user of PyScripter suggested the following script for running QGIS with PyScripter (which uses P4D) after copying the dll and python.exe files.

call "%OSGEO4W_ROOT%\bin\o4w_env.bat"
call qt5_env.bat
call py3_env.bat
path %OSGEO4W_ROOT%\apps\qgis\bin;%PATH%
set QGIS_PREFIX_PATH=%OSGEO4W_ROOT:\=/%/apps/qgis
set GDAL_FILENAME_IS_UTF8=YES
rem Set VSI cache to be used as buffer, see #6448
set VSI_CACHE=TRUE
set VSI_CACHE_SIZE=1000000
set QT_PLUGIN_PATH=%OSGEO4W_ROOT%\apps\qgis\qtplugins;%OSGEO4W_ROOT%\apps\qt5\plugins
set PYTHONPATH=%OSGEO4W_ROOT%\apps\qgis\python;%PYTHONPATH%
start "PyScripter" %~pd0\PyScripter.exe --PYTHON36 --pythondllpath=%OSGEO4W_ROOT%\apps\python36

Copy link
Contributor Author

idanmiara commented Oct 25, 2018 via email

Hi, RE: Why don't you call GetPythonVersionFromDLLName in your code: I could do that. but I think that if you provide a property it should be valid for reading the state of the dll that was loaded. I didn't say It's a major bug, just a small fix. RE: LatestPythonVersionFromPath, I agree it's a corner case, but it's also platform independent and it's doesn't affect the normal use case (it would give the same result as the original function), so I don't see a reason not to add it. I do need to call SetPythonHome with a modified path, but I don't see your point about that. RE: PyScripter, I didn't know that program, I'll have a look, thanks :) RE: Batch file: I know that method and sometimes use it (i.e. before I used SetPythonHome and for using QGIS python with a different IDE), but I'm trying to make my app run without a wrapping batch file. I'm not sure about the reasons that QGIS/OSGeo4W chose this uncommon setup, but it's less likely to change soon...
...
On 2018年10月25日 at 18:25, pyscripter ***@***.***> wrote: I am considering including GetPythonVersionFromDLLName and possibly LatestPythonVersionFromPath but I still do not see the purpose of your other changes: What is the use of changing DoOpenDLL? You say that The problem I'm trying to solve is as follows: UserInputDllName := ''; // allow user to input UserInputDllName if he wishes. PyEngine.DllName := UserInputDllName; PyEngine.UseLastKnownVersion := PyEngine.DllName=''; now I want to read PyEngine.RegVersion and I will get a wrong answer in case the user specified the DLL name. Why don't you call GetPythonVersionFromDLLName in your code i.e if UserInputDLLName <> '' then PythonEngine.RegVersion := GetPythonVersionFromDLLName(UserInputDLLName); Also regarding LatestPythonVersionFromPath. This actually deals with a corner case and anyway enen after using this method you still have to call SetPythonHome with a different path than the DLLPath. The simple solution for QGIS would be to copy the dll and python exe files to the python directory, By the way a QGIS user of PyScripter suggested the following script for running QGIS with PyScripter (which uses P4D) after copying the dll and python.exe files. call "%OSGEO4W_ROOT%\bin\o4w_env.bat" call qt5_env.bat call py3_env.bat path %OSGEO4W_ROOT%\apps\qgis\bin;%PATH% set QGIS_PREFIX_PATH=%OSGEO4W_ROOT:\=/%/apps/qgis set GDAL_FILENAME_IS_UTF8=YES rem Set VSI cache to be used as buffer, see #6448 set VSI_CACHE=TRUE set VSI_CACHE_SIZE=1000000 set QT_PLUGIN_PATH=%OSGEO4W_ROOT%\apps\qgis\qtplugins;%OSGEO4W_ROOT%\apps\qt5\plugins set PYTHONPATH=%OSGEO4W_ROOT%\apps\qgis\python;%PYTHONPATH% start "PyScripter" %~pd0\PyScripter.exe --PYTHON36 --pythondllpath=%OSGEO4W_ROOT%\apps\python36 — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub <#62 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AZIQrQmUNAqKu-DbKXBB3WZWInXADkGOks5uodfPgaJpZM4X4OaN> .

Idan Miara added 4 commits December 6, 2018 12:22
+ GetDllFileName = DllPath + DllName
+ CreateInstance, CreateInstanceAndLoad - creates an instance of the dll
+ MapDll (abstract virtual), CallMapDll - CallMapDll will be called in AfterLoad
+ LoadDll - now a function instead of procedure, returns validity.
+ DoOpenDll - use default dllname if empty string is passed; fix for loading dlls in subdirs (previous method would fail depending on its depended DLLs)
+ Import now accepts UnicodeStrings
+ Import2 for handling STDCall on 32bit
+ DllPath now writes via a function SetDllPath
+ DllFullFileName added a property that returns the full path of the dll
PythonEngine.pas - TPythonInterface
+ AfterLoad - split functionality between TPythonInterface.MapDll and TDynamicDll.CallMapDll
+ GetDllPath - add the special behavior for the PythonDLL (IsPythonVersionRegistered) which has nothing to do in TDynamicDll
+ MapDll - added functionality from TPythonInterface.GetDllPath; Import now accepts UnicodeString and not AnsiString
Copy link
Contributor Author

Hi,
I've rebased my changes on your master.
I'm using your TDynamicDll as a base for other dlls that I use.
I pushed some additions and fixes.
Should I keep posting improvements to this library? If you are willing to accept contributions I will keep post them.

@idanmiara idanmiara changed the title (削除) Detect Python RegVersion correctly for UseLastKnownVersion=False (削除ここまで) (追記) TDynamicDLL improvements and other fixes (追記ここまで) Dec 6, 2018
Copy link
Owner

The scope of the PR is becoming too wide, including different changes for different purposes. I am closing this. You are welcome to submit different PRs with narrow scope and specific purpose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /