2014-11-18 9 views
5

Próbuję zainicjować Runtime (MCR) kompilatora Matlab z Pythona za pomocą ctypes. Moim celem końcowym jest możliwość użycia biblioteki DLL C stworzonej przez kompilator Matlaba w Pythonie, ale pierwszą przeszkodą, którą muszę pokonać, jest uruchomienie MCR.Python ctypes: Jak przekazać NULL jako argument o formacie const char **

Używam Python 2.7.8, Matlab 2013a, MCR8.1.

Snipit z mclbase.h pokazać argumenty itp

LIBMWMCLBASE_API_EXTERN_C bool mclInitializeApplication(const char** options, size_t count); 

C równowartość co usiłuję zrobić

mclInitializeApplication(NULL,0) 

Oto moje różne próby wywołania funkcji w Pythonie. Nieuchronnie powstają w TypeErrors lub Windows Error 0xE06D7363. Nie mogę tego złamać! Jestem początkującym pytonem, więc może być coś prostego, czego mi brakuje. Wszelkie komentarze mile widziane!

# 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 dodając pytona wyjątków rzuca

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

Okazuje się, brakowało mi wezwanie do mclmcrInitialize() jak @eryksun poinformował, . Mogę teraz wywoływać funkcje (hooray!), Ale inicjalizacja nie powiodła się :(Tak więc postęp, ale nadal działa! Oto kod na wypadek, gdyby był dla nikogo użyteczny. Mam wiele połączeń z mclIsMCRInitialized() i mclGetLastErrorMessage() w . tam, że są wypełniająca rzeczy trochę, ale może dostarczyć przydatnych informacji debugowania

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 

Oto wyjście z pytona:

mclmcrInitialize returned 
-2147483647 
mclIsMCRInitialized = 
False 
mcl last error returns 
124384774 
mclInitializeApplication returned 
False 
mclIsMCRInitialized = 
False 
mcl last error returns 
128050512 
mclTerminateApp returned 
True 
+1

To tylko 'mclInit (None, 0)'. To, że widzisz nieobsługiwany wyjątek VC++ ('0xE06D7363', tj." Msc ") implikuje głębszy problem. Czy jest coś, co należy uruchomić najpierw, aby zainicjować MATLAB? Widzę odniesienia do 'mclmcrInitialize'. – eryksun

+2

Nawiasem mówiąc, ctypes nie obsługuje w ogóle wyjątków C++. Widzisz tylko wyjątek VC++, ponieważ Microsoft implementuje go przy użyciu wyjątku Windows, który obsługuje cpy. Zwykle nieobsługiwany wyjątek C++ zakończyłby proces. – eryksun

+0

Myślę, że moje wyłączenie 'mclmcrInitialize' może być częścią problemu w porządku.Śledziłem podaną tutaj ogólną formę [link] (http://blogs.mathworks.com/loren/2011/02/03/creating-c-shared-libraries-and-dlls/), która nie wydaje się wspomnij o tym, ale teraz wiem, że go szukam Widzę wiele odniesień do tego. Powiadomię, jeśli wszystko będzie gotowe! – ClaireM

Odpowiedz

0

Podczas gdy my sądzimy, można spróbować:

mclInit.argtypes = [POINTER(c_char_p), c_size_t] 
a = POINTER(c_char_p)() 
b = c_size_t(0) 
ret = mclInit(byref(a), b) 
+0

Warto spróbować, ale niestety nasz stary przyjaciel "[Error -529697949] Błąd systemu Windows 0xE06D7363" jest wynikiem, gdy go uruchomię. Myślę, że konfiguracja typu argumentów jest poprawna, ale teraz podejrzewam, że jest coś, czego brakuje, powodując problemy. – ClaireM

1

Zamieszczam to w odpowiedzi na prośbę @Kcevina. Niestety musiałem odinstalować MCR ze względu na ograniczenia miejsca na moim komputerze, więc nie mogłem tego przetestować dzisiaj, ale myślę, że ten kod powinien być rozsądnie funkcjonalny i stabilny. Próbowałem opublikować go w komentarzach, ale wydaje się, że nie pozwala na duże fragmenty kodu, więc stworzyłem tę odpowiedź. To tylko inicjuje i kończy MCR i moją własną bibliotekę DLL. Oczywiście musisz zmienić nazwy ścieżek itp., Aby dopasować swoją własną sprawę. Nie dostałem tak daleko, jak wywołanie funkcji z biblioteki DLL lub przekazanie zmiennych do wspomnianych funkcji, ale mam nadzieję, że jest to przydatne.

To wszystko, co mam z tym problemem. Nowy silnik python na Matlab R2014b oznaczał, że nie musiałem tego dalej.

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() 
Powiązane problemy