Hello pymatlab team,
I tried to use PyMatlab on a windows computer with Python 3. In order to run it under windows, I had to adapt the script a litte bit and want to inform you about my changes, such that you can possibly add them to future releases.
The first change I had to made is in sessionfactory.py:
def session_factory(options='',output_buffer_size=8096): ... elif system =='Windows': locations = os.environ.get("PATH").split(os.pathsep) for location in locations: if platform.architecture()[0] == '32bit': subfolder = 'win32' else: #64bit subfolder = 'win64' candidate = os.path.join(location, 'matlab.exe') if os.path.isfile(candidate): lib = os.path.join(location, 'libeng.dll') if os.path.isfile(lib): path = lib break; lib = os.path.join(location, subfolder, 'libeng.dll') if os.path.isfile(lib): path = lib break; executable = os.path.realpath(path) basedir = os.path.dirname(executable) session = MatlabSession(basedir,bufsize=output_buffer_size)
At first, one minor error in the last line. basedir has been based using the keyword argument path. This does not exist in class MatlabSession (therefore removed). Additionally, the matlab.exe exists twice on Windows PC. One time in one base folder and one time in a subfolder 'win32' or 'win64'. In this subfolder are the relevant 'libeng.dll' and 'libmx.dll'. Therefore I try to find out whether Python is compiled in 32 or 64bit and indicate the corresponding subfolder, since a 32bit Python cannot load a 64bit Matlab and vice-versa. Then I check if matlab.exe from the base directory or the subfolder has been indicated by the PATH variable by looking for libeng.dll as well. If found, basedir contains the path to the subfolder 'win32' or 'win64'. I hope this code also works on Python 2. Maybe some error messages might be good if no appropriate Matlab could be found.
As second thing, I needed to change the constructor of class MatlabSession, since 'libeng.dll' and 'libmx.dll' are directly located in the given basedir, hence in the win32 or win64 subfolder. Here the code
class MatlabSession(object): def __init__(self,matlab_root='',command='',bufsize=128): system = platform.system() if system=='Linux' or system=='Darwin': self.engine = CDLL(join(matlab_root,'bin','glnxa64','libeng.so')) self.mx = CDLL(join(matlab_root,'bin','glnxa64','libmx.so')) self.ep = self.engine.engOpen(c_char_p(command)) elif system=='Windows': self.engine = CDLL(join(matlab_root,'libeng.dll')) self.mx = CDLL(join(matlab_root,'libmx.dll')) self.ep = self.engine.engOpen(None) else: raise NotImplementedError( 'system {} not yet supported'.format(system)) if self.ep is None: raise RuntimeError( 'Could not start matlab using command "{}"'.format(command)) self.buff_length = bufsize if self.buff_length!=0: self.buf = create_string_buffer(self.buff_length) self.engine.engOutputBuffer(self.ep,self.buf,self.buff_length-1)
I also have some further fixes for Python 3 (it works on my PC now). However it might probably better to address this in an extra issue.
Cheers
Marc