2014-11-18 14 views
5

Ich versuche, Matlab Compiler Runtime (MCR) von Python mit Ctypes zu initialisieren. Mein Endziel ist es, eine C-DLL verwenden zu können, die vom Matlab-Compiler in Python erstellt wurde, aber die erste Hürde, die ich überwinden muss, ist, MCR zum Laufen zu bringen.Python Ctypes: Wie übergeben NULL als Argument mit Format Const Char **

Ich benutze Python 2.7.8, Matlab 2013a, MCR8.1.

Snipit von mclbase.h die Argumente zu zeigen, etc

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

C entspricht das, was ich versuche,

mclInitializeApplication(NULL,0) 

Hier sind meine verschiedenen Versuche zu tun, um die Funktion in Python zu nennen. Sie führen unweigerlich zu TypeErrors oder Windows Error 0xE06D7363. Ich kann es nicht knacken! Ich bin ein Python-Neuling, also kann es etwas einfaches sein, das ich vermisse. Alle Kommentare willkommen!

# 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") 

bearbeiten: Gerade in der Python-Ausnahmen hinzugefügt wirft

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 stellt sich heraus, dass ich einen Aufruf an mclmcrInitialize() fehlte als @eryksun darauf hingewiesen hatte, . Ich kann jetzt die Funktionen aufrufen (hurra!) Aber die Initialisierung ist nicht erfolgreich :(. Also ein paar Fortschritte, aber immer noch zu arbeiten! Hier ist der Code für den Fall jemand anderen. Ich habe eine Reihe von Anrufen zu mclIsMCRInitialized() und mclGetLastErrorMessage() in . gibt, die ein wenig Dinge sind Bauschen aber möglicherweise hilfreiche Informationen debug liefern

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 

Hier ist die Ausgabe von python:

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

Es ist nur 'mclInit (None, 0)'. Dass Sie eine unbehandelte VC++ - Ausnahme ('0xE06D7363', d. H." Msc ") sehen, deutet auf ein tiefer liegendes Problem hin. Gibt es etwas, das zuerst ausgeführt werden muss, um MATLAB zu initialisieren? Ich sehe Verweise auf 'mclmcrInitialize'. – eryksun

+2

Übrigens, Ctypes hat keine Unterstützung für C++ - Ausnahmen im Allgemeinen. Sie sehen nur die VC++ - Ausnahme, da Microsoft sie mit einer Windows-Ausnahme implementiert, die ctypes behandelt. Normalerweise würde eine unbehandelte C++ Ausnahme den Prozess beenden. – eryksun

+0

Ich glaube, mein Ausschluss von 'mclmcrInitialize' könnte Teil des Problems sein.Ich folgte dem allgemeinen Formular [link] (http://blogs.mathworks.com/loren/2011/02/03/creating-c-shared-libraries-and-dlls/), das anscheinend nicht funktioniert Erwähnen Sie es, aber jetzt weiß ich, um danach zu suchen Ich sehe eine Menge Bezug darauf. Ich melde mich, wenn ich die Dinge in Gang setze! – ClaireM

Antwort

0

Während wir raten, könnten Sie versuchen:

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

einen Versuch wert, aber leider unser alter Freund '[Fehler -529697949] Windows Fehler 0xE06D7363' ist das Ergebnis, wenn ich es ausführe. Ich denke, dass die Art des Setups der Argumente korrekt ist, aber ich vermute jetzt, dass etwas fehlt, was Probleme verursacht. – ClaireM

1

Ich poste dies als Antwort auf eine Anfrage von @Krcevina. Leider musste ich MCR aus Platzgründen auf meinem PC deinstallieren, so dass ich das heute nicht testen konnte, aber ich denke, dass dieser Code einigermaßen funktional und stabil sein sollte. Ich habe versucht, es in den Kommentaren zu posten, aber es scheint keine großen Codefragmente zuzulassen, daher habe ich diese Antwort erstellt. Es initialisiert und beendet nur die MCR und meine eigene DLL. Natürlich müssen Sie die Pfadnamen ändern, um sie an Ihren eigenen Fall anzupassen. Ich war noch nicht so weit gekommen, eine Funktion von der DLL aus aufzurufen oder Variablen an diese Funktionen zu übergeben, aber hoffentlich ist das für Sie von Nutzen.

Das ist so weit wie ich mit diesem Problem habe. Die neue Python-Engine auf Matlab R2014b bedeutete, dass ich das nicht weiter machen musste.

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() 
Verwandte Themen