Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python ctypes: How to pass NULL as argument with format const char **

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
like image 526
ClaireM Avatar asked Nov 18 '14 13:11

ClaireM


1 Answers

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)
like image 64
101 Avatar answered Sep 30 '22 20:09

101