I'm trying to initialise Matlab compiler Runtime (MCR) from python using ctypes. My end goal is to be able to use a C DLL created by Matlab compiler in python, but the first hurdle I need to get over is getting MCR up and running.
I'm using Python 2.7.8, Matlab 2013a, MCR8.1.
Snipit from mclbase.h to show the arguments etc
LIBMWMCLBASE_API_EXTERN_C bool mclInitializeApplication(const char** options, size_t count);
C equivalent of what I'm trying to do
mclInitializeApplication(NULL,0)
Here's my various attempts to call the function in python. They result inevitably in TypeErrors or Windows Error 0xE06D7363. I can't crack it! I'm a python newbie so there may be something simple I'm missing. Any comments welcome!
# Initialize the MATLAB Compiler Runtime global state
from ctypes import *
libmcr=cdll.mclmcrrt8_1
# Load mclbase library
mcr_dll = cdll.LoadLibrary('C:\\Program Files\\MATLAB\\MATLAB Compiler Runtime\\v81\\bin\\win64\\mclbase.dll')
# Pick function we want to use
mclInit=mcr_dll.mclInitializeApplication
# Set up argument and results types
mclInit.argtypes = [POINTER(POINTER(c_char)),c_size_t]
# mclInit.argtypes = [POINTER(c_char_p),c_size_t] #different formatting attempt
mclInit.restype = c_bool
a=None
acast=cast(a,POINTER(c_char_p))
acast1=cast(a,POINTER(c_char))
acast2=cast(a,POINTER(POINTER(c_char)))
print 'a='
print a
print 'acast='
print acast
print 'acast1='
print acast1
print ''
# Try calling the function with various argument types
try:
b=mclInit(None,0)
except Exception as ex:
print ex
raw_input("Exception occurred. b=mclInit(None,0) didn't work. Press Enter to continue")
print ''
try:
b=mclInit(byref(acast),0)
except Exception as ex:
print ex
raw_input("b=mclInit(byref(acast),0) didn't work. Press Enter to continue")
print ''
try:
b=mclInit(acast,0)
except Exception as ex:
print ex
raw_input("b=mclInit(acast,0) didn't work. Press Enter to continue")
print ''
try:
b=mclInit(byref(acast1),0)
except Exception as ex:
print ex
raw_input("mclInit(byref(acast1) didn't work. Press Enter to continue")
print ''
try:
b=mclInit(acast1,0)
except Exception as ex:
print ex
raw_input("b=mclInit(acast1,0) didn't work. Press Enter to continue")
print ''
try:
b=mclInit(byref(acast2),0)
except Exception as ex:
print ex
raw_input("mclInit(byref(acast2) didn't work. Press Enter to continue")
print ''
try:
b=mclInit(acast2,0)
except Exception as ex:
print ex
raw_input("b=mclInit(acast2,0) didn't work. Press Enter to continue")
print ''
raw_input("Reached the end!!!! Press enter to close")
Edit: Just adding in the exceptions python throws
a=
None
acast=
<__main__.LP_c_char_p object at 0x00000000034E68C8>
acast1=
<ctypes.LP_c_char object at 0x00000000034E6948>
[Error -529697949] Windows Error 0xE06D7363
Exception occurred. b=mclInit(None,0) didn't work. Press Enter to continue
argument 1: <type 'exceptions.TypeError'>: expected LP_LP_c_char instance instea
d of pointer to LP_c_char_p
b=mclInit(byref(acast),0) didn't work. Press Enter to continue
argument 1: <type 'exceptions.TypeError'>: expected LP_LP_c_char instance instea
d of LP_c_char_p
b=mclInit(acast,0) didn't work. Press Enter to continue
[Error -529697949] Windows Error 0xE06D7363
mclInit(byref(acast1) didn't work. Press Enter to continue
[Error -529697949] Windows Error 0xE06D7363
b=mclInit(acast1,0) didn't work. Press Enter to continue
argument 1: <type 'exceptions.TypeError'>: expected LP_LP_c_char instance instea
d of pointer to LP_LP_c_char
mclInit(byref(acast2) didn't work. Press Enter to continue
[Error -529697949] Windows Error 0xE06D7363
b=mclInit(acast2,0) didn't work. Press Enter to continue
EDIT 2
So it turns out I was missing a call to mclmcrInitialize()
as @eryksun had pointed out. I can now call the functions (hooray!) but the initialisation is not successful :( . So some progress but still work to do! Here's the code in case its of use to anyone. I have a number of calls to mclIsMCRInitialized()
and mclGetLastErrorMessage()
in there that are bulking things out a bit but might provide helpful debug information.
from ctypes import *
libmcr=cdll.mclmcrrt8_1
# Load mclmcr library
mclmcr_dll = cdll.LoadLibrary('C:\\Program Files\\MATLAB\\MATLAB Compiler Runtime\\v81\\bin\\win64\\mclmcr.dll')
# Load mclbase library
mclbase_dll = cdll.LoadLibrary('C:\\Program Files\\MATLAB\\MATLAB Compiler Runtime\\v81\\bin\\win64\\mclbase.dll')
# Call mclmcrInitialize()
mclmcrInit = mclmcr_dll.mclmcrInitialize
mclmcrInit.argtypes = None
mclmcrInit.restypes = c_bool
a = mclmcrInit()
print "mclmcrInitialize returned "
print a
# call mclIsMCRInitialized()
mclIsMCRInit = mclbase_dll.mclIsMCRInitialized
mclIsMCRInit.argtypes = None
mclIsMCRInit.restype = c_bool
b = mclIsMCRInit()
print "mclIsMCRInitialized = "
print b
# Call mclGetLastErrorMessage()
mclGetLastErrMsg = mclbase_dll.mclGetLastErrorMessage
mclGetLastErrMsg.argtypes = None
mclGetLastErrMsg.restypes = c_char_p
err = mclGetLastErrMsg()
print "mcl last error returns "
print err
# call mclInitializeApplication(NULL,0)
mclInit = mclbase_dll.mclInitializeApplication
mclInit.argtypes = [POINTER(c_char_p),c_size_t]
mclInit.restype = c_bool
b = mclInit(None,0)
print "mclInitializeApplication returned "
print b
# call mclIsMCRInitialized()
mclIsMCRInit = mclbase_dll.mclIsMCRInitialized
mclIsMCRInit.argtypes = None
mclIsMCRInit.restype = c_bool
b = mclIsMCRInit()
print "mclIsMCRInitialized = "
print b
# Call mclGetLastErrorMessage()
mclGetLastErrMsg = mclbase_dll.mclGetLastErrorMessage
mclGetLastErrMsg.argtypes = None
mclGetLastErrMsg.restypes = c_char_p
err = mclGetLastErrMsg()
print "mcl last error returns "
print err
# Call mclTerminateApplication()
mclTerminate = mclbase_dll.mclTerminateApplication
mclTerminate.argtypes = None
mclTerminate.restype = c_bool
f = mclTerminate()
print "mclTerminateApp returned "
print f
Here's the output from python:
mclmcrInitialize returned
-2147483647
mclIsMCRInitialized =
False
mcl last error returns
124384774
mclInitializeApplication returned
False
mclIsMCRInitialized =
False
mcl last error returns
128050512
mclTerminateApp returned
True
I'm posting this in response to a request by @Krcevina. Unfortunately I had to uninstall MCR due to space constraints on my PC so haven't been able to test this today but I think this code should be reasonably functional and stable. I tried to post it in the comments but it doesn't seem to allow for large code fragments so I've created this answer. It just initialises and terminates the MCR and my own DLL. Obviously you'll need to change path names etc to match your own case. I hadn't gotten as far as calling a function from the DLL or passing variables to said functions but hopefully this is of some use to you.
This is as far as I got with this issue. The new python engine on Matlab R2014b meant I didn't need to take this any further.
from ctypes import *
libmcr=cdll.mclmcrrt8_1
# Just check to make sure its 64bit python I'm using...
print "4 for 32bit, 8 for 64bit:"
print sizeof(c_voidp)
# Load mclmcr library
mclmcr_dll = cdll.LoadLibrary('C:\\Program Files\\MATLAB\\MATLAB Compiler Runtime\\v81\\bin\\win64\\mclmcr.dll')
# Load mclbase library
mclbase_dll = cdll.LoadLibrary('C:\\Program Files\\MATLAB\\MATLAB Compiler Runtime\\v81\\bin\\win64\\mclbase.dll')
# Load matrix library
matrix_dll = cdll.LoadLibrary('C:\\Program Files\\MATLAB\\MATLAB Compiler Runtime\\v81\\bin\\win64\\libmx.dll')
# Load ClairesTestInterface library
claires_dll = cdll.LoadLibrary('ClairesTestCompile.dll')
#typedef int (*mclMainFcnType)(int, const char **);
mclMainFcnType=CFUNCTYPE(c_int, c_int, POINTER(c_char_p) ) # (returnvalu, arg1, arg2)
def run_main(argc,argv):
print "run_main entered."
# call mclInitializeApplication(NULL,0)
mclInitializeApplication = mclbase_dll.mclInitializeApplication
mclInitializeApplication.argtypes = [POINTER(c_char_p),c_size_t]
mclInitializeApplication.restype = c_bool
b = mclInitializeApplication(None,0)
print "mclInitializeApplication returned "
print b
# call mclIsMCRInitialized()
mclIsMCRInitialized = mclbase_dll.mclIsMCRInitialized
mclIsMCRInitialized.argtypes = None
mclIsMCRInitialized.restype = c_bool
b = mclIsMCRInitialized()
print "mclIsMCRInitialized = "
print b
# call ClairesTestCompileInitialize()
ClairesTestCompileInitialize = claires_dll.ClairesTestCompileInitialize
ClairesTestCompileInitialize.argtypes = None
ClairesTestCompileInitialize.restype = c_bool
b = ClairesTestCompileInitialize()
print "ClairesTestCompileInitialize = "
print b
## -------------------------------------------------------------------------------------------------------
## -------------------------------------------------------------------------------------------------------
# call ClairesTestCompileTerminate()
ClairesTestCompileTerminate = claires_dll.ClairesTestCompileTerminate
ClairesTestCompileTerminate.argtypes = None
ClairesTestCompileTerminate.restype = None
ClairesTestCompileTerminate()
print "ClairesTestCompileTerminate has run "
# Call mclTerminateApplication()
mclTerminateApplication = mclbase_dll.mclTerminateApplication
mclTerminateApplication.argtypes = None
mclTerminateApplication.restype = c_bool
f = mclTerminateApplication()
print "mclTerminateApp returned "
print f
print "Reached the end of run_main()!!!"
return b
def main():
print "main() entered."
# Call mclmcrInitialize()
mclmcrInitialize = mclmcr_dll.mclmcrInitialize
mclmcrInitialize.argtypes = None
mclmcrInitialize.restypes = c_bool
a = mclmcrInitialize()
print "mclmcrInitialize returned "
print a
#LIBMWMCLBASE_API_EXTERN_C int mclRunMain(mclMainFcnType run_main, int argc, const char **argv);
mclRunMain=mclbase_dll.mclRunMain
mclRunMain.argtypes = [mclMainFcnType, c_int, POINTER(c_char_p)]
mclRunMain.restype = c_int
try:
_run_main = mclMainFcnType(run_main) # reference the callback to keep it alive
except Exception as ex:
print ex
#print "callback referenced to keep it alive."
c = mclRunMain(_run_main, 0, None)
print "mclRunMain returned "
print c
raw_input("Reached the end of main()! Press enter to close")
main()
While we're guessing, you could try:
mclInit.argtypes = [POINTER(c_char_p), c_size_t]
a = POINTER(c_char_p)()
b = c_size_t(0)
ret = mclInit(byref(a), b)
User contributions licensed under CC BY-SA 3.0