Python ctypes:如何将NULL作为参数传递,格式为const char**

Cla*_*reM 7 null ctypes pointers python-2.7

我正在尝试使用ctypes从python初始化Matlab编译器运行时(MCR).我的最终目标是能够在python中使用由Matlab编译器创建的C DLL,但我需要克服的第一个障碍就是启动并运行MCR.

我正在使用Python 2.7.8,Matlab 2013a,MCR8.1.

从mclbase.h剪切以显示参数等

LIBMWMCLBASE_API_EXTERN_C bool mclInitializeApplication(const char** options, size_t count);
Run Code Online (Sandbox Code Playgroud)

C相当于我正在尝试做的事情

mclInitializeApplication(NULL,0)
Run Code Online (Sandbox Code Playgroud)

这是我在python中调用函数的各种尝试.它们不可避免地导致TypeErrors或Windows错误0xE06D7363.我无法破解它!我是一个蟒蛇新手所以可能有一些简单的我缺少.欢迎任何评论!

# 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")
Run Code Online (Sandbox Code Playgroud)

编辑:只需添加异常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
Run Code Online (Sandbox Code Playgroud)

编辑2

所以事实证明我错过了mclmcrInitialize()@eryksun指出的电话.我现在可以调用这些函数(万岁!),但是初始化不成功:(.所以有些进展但仍有工作要做!这是代码,以防它对任何人使用.我有很多调用,mclIsMCRInitialized()mclGetLastErrorMessage()在那里正在填补一些东西,但可能提供有用的调试信息.

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
Run Code Online (Sandbox Code Playgroud)

这是python的输出:

mclmcrInitialize returned
-2147483647
mclIsMCRInitialized =
False
mcl last error returns
124384774
mclInitializeApplication returned
False
mclIsMCRInitialized =
False
mcl last error returns
128050512
mclTerminateApp returned
True
Run Code Online (Sandbox Code Playgroud)

101*_*101 1

当我们猜测时,您可以尝试:

mclInit.argtypes = [POINTER(c_char_p), c_size_t]
a = POINTER(c_char_p)()
b = c_size_t(0)
ret = mclInit(byref(a), b)
Run Code Online (Sandbox Code Playgroud)