4 Stimmen

Wie kann ich verhindern, dass Py_Initialise die Anwendung zum Absturz bringt?

Von VBA und VB6 aus rufe ich eine DLL auf, die einen Python-Interpreter erzeugt. Wenn ich die PATH Umgebungsvariable, die auf "C:\python27" y PYTHONPATH a "c:\python27\lib" ist alles in Ordnung.

Wenn ich nicht die PATH und ruft dann Py_Initialise() stürzt XL oder meine VB6-Anwendung ab, auch wenn ich Py_SetProgramName con "c:\python27\python27.exe" Erstens.

Ich möchte die Installation in VB/VBA angeben, anstatt sie in der Umgebung festzulegen, da ich das in XL nicht tun kann (funktioniert gut für VB6).

3voto

DangerMouse Punkte 704

Die beste Antwort, die ich bis jetzt gefunden habe, ist, dass es sich um einen Fehler in Python handelt - http://bugs.python.org/issue6498 . Der Intepreter scheint bei bestimmten Fehlern exit() aufzurufen, statt einen Code an den Aufrufer zurückzugeben. Nicht sehr freundlich, wenn Sie Python in eine Anwendung einbetten. Aber da haben Sie es.

1voto

Thomas Punkte 2095

Versuchen Sie, das Arbeitsverzeichnis zu wechseln, bevor Sie die DLL aufrufen:

In Ihrem VBA-Code:

chdir("c:\python27\") '- change the working-directory for python
=> call dll '- call the dll
chdir(app.Path) '- change back to your folder (maybe you want to save your current folder bevore you change it the first time and change back to this?!)

Grüße Thomas

0voto

Thomas Punkte 2095

Sie können einfach überprüfen, ob die benötigte Umgebungsvariable gesetzt ist:

dim PPath as string
PPath = trim(Environ("PYTHONPATH"))
if (PPath<>"")
  <call dll>
else
  msgbox ("Error!")
end if

Oder Sie können die DLL in einem anderen Testprozess ausführen: Wenn dieser Aufruf funktioniert, wissen Sie, dass es OK ist, die DLL aufzurufen - es hängt von dem DLL-Aufruf ab, den Sie verwenden, daher bin ich mir da nicht sicher:

Private Declare Function CloseHandle Lib "kernel32" (ByVal _
    hObject As Long) As Long

Private Declare Function OpenProcess Lib "kernel32" (ByVal _
    dwDesiredAccess As Long, ByVal bInheritHandle As _
    Long, ByVal dwProcessId As Long) As Long

Private Declare Function GetExitCodeProcess Lib "kernel32" _
    (ByVal hProcess As Long, lpExitCode As Long) As Long

Const STILL_ACTIVE = &H103
Const PROCESS_ALL_ACCESS = &H1F0FFF

...
dim IsActive as boolean
dim Handle as long
Dim TaskID As Long
TaskID = Shell("rundll32.exe pyton.dll Py_Initialise()", vbNormalNoFocus)

<wait for some time>

'- check if pyton.dll is still running
Handle = OpenProcess(PROCESS_ALL_ACCESS, False, TaskID)
Call GetExitCodeProcess(Handle, ExitCode)
Call CloseHandle(Handle)

IsActive = IIf(ExitCode = STILL_ACTIVE, True, False)

if (not IsActive) then
  msgbox ("Error!")
else
  <kill process>
  <call dll normally>
end if

Mit freundlichen Grüßen Thomas

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X