how to convert a python script with matlab function called to exe?

5 ビュー (過去 30 日間)
NICK G
NICK G 2018 年 4 月 20 日
回答済み: ChangYuan Liu 2021 年 3 月 16 日
I write a function in MATLAB and use the "Library Compiler" to convert it to "Python Packages", then i write a python script to do some other things and call the function in the Python Packages. Both the function and the script run perfectly in MATLAB PythonCMD or windowsPowerShell.
But i need to get a standalone application running on windows platform. I use pyinstaller to convert it into exe, but i can not run the exe.It says:
PS C:\Users\86732\Desktop\program\dist> .\easytest.exe
Traceback (most recent call last):
File "program\easytest.py", line 2, in <module>
File "program\DrawPkg\__init__.py", line 301, in initialize
File "program\DrawPkg\__init__.py", line 249, in initialize_package
File "D:\MATLAB2017b\toolbox\compiler_sdk\pysdk_py\matlab_pysdk\runtime\deployablepackage.py", line 33, in initialize
mcr_handle = self.__cppext_handle.startMatlabRuntimeInstance(self.__ctf_path)
SystemError: Cannot find CTF archive 'AppData\Local\Temp\_MEI45282\DrawPkg\DrawPkg.ctf'.
[13564] Failed to execute script easytest
I have tried to put 'DrawPkg' whole folder to the same folder of easytest.py, still not work
my MATLAB function:
function DrawCurveBoard(tmp_Rho1, tmp_Height1)
blabla..(no output)
and my Python Script follows: (runs fine in the form of script)
import DrawPkg
my = DrawPkg.initialize()
Rho1 = float(input(' first Rho1:'))
Height1 = float(input(' first Height1:'))
my.DrawCurveBoard(Rho1, Height1, nargout=0)
pack to exe:(It says successfully)
pyinstaller -F -c ./easytest.py
Does anyone know where the problem is? I tried many ways but still cannot get the .exe work :(

採用された回答

Sam McCormack
Sam McCormack 2020 年 5 月 2 日
編集済み: Sam McCormack 2020 年 5 月 3 日
Matlab-packaged libraries are a wrapper around a CTF archive. The CTF archive is essentially a .zip file which contains your packaged code; when the Matlab-packaged library is imported in Python, the Matlab Runtime extracts the CTF archive and loads the code.
The problem with PyInstaller is that it doesn't know where the CTF file is, so it doesn't bundle it with the program. We can fix this by supplying the correct items to the datas field in the PyInstaller .spec file.
-----
Let's say you have a Matlab-packaged library called TestLibrary. For simplicity, the library packages a function also called TestLibrary (my packages are usually a function packaged as a library with the same name). The structure of the package produced by Matlab will look like this (unimportant files omitted):
TestLibrary / for_redistribution_files_only / TestLibrary / TestLibrary.ctf
The file PyInstaller needs to bundle with the program is "TestLibrary.ctf". For the purposes of this example, the base TestLibrary folder exists in the same folder as the Python script, which is called myscript.py.
If you're not using a .spec file, run your PyInstaller command:
# You could also add arguments such as "-F".
PyInstaller myscript.py
This will create a myscript.spec file which we'll modify and use for future builds.
When TestLibrary is imported in Python, the Matlab Runtime looks for "TestLibrary/TestLibrary.ctf" in the folder where the .exe resides. To add the folder with the CTF file to the bundled program, edit myscript.spec and set the datas parameter in the Analysis call:
### .... ###
a = Analysis(['myscript.py'],
pathex=['C:\\example'],
binaries=[],
datas=[
("TestLibrary/for_redistribution_files_only/TestLibrary", "TestLibrary"),
],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
### .... ###
("TestLibrary/for_redistribution_files_only/TestLibrary", "TestLibrary") means that the folder containing the CTF archive will be available alongside the executable in a folder, TestLibrary. The Matlab Runtime will then be able to load the CTF file.
Now run PyInstaller with the .spec file:
PyInstaller myscript.spec
A working standalone program should be built and packaged in the dist directory.
This works with standalone programs bundled as a single executable, as well as standalone programs bundled as an executable in a folder. As a sidenote, I recommend the latter approach (one-directory) because the one-file executable has unnecessary overhead which slows the program down.
-----
Since the .spec file is Python code, you can also write a function to generate the value of datas when you run PyInstaller.
My approach is as follows:
  • All Matlab-packaged libraries are saved inside a packages folder.
  • A function in the .spec file finds all suitable folders inside the packages folder, and the result is used as the datas parameter.

その他の回答 (1 件)

ChangYuan Liu
ChangYuan Liu 2021 年 3 月 16 日
Thank you for the answer! Your answer helped me a lot!

カテゴリ

Help Center および File ExchangePython Package Integration についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by