如何防止Py_Initialise崩溃应用程序?

4 投票
3 回答
1788 浏览
提问于 2025-04-17 03:09

我在用VBA和VB6调用一个dll,这个dll可以创建一个Python解释器。如果我把PATH这个环境变量设置为指向"C:\python27",同时把PYTHONPATH设置为"c:\python27\lib",一切都正常。

但是如果我不设置PATH,那么调用Py_Initialise()就会导致Excel或者我的VB6应用崩溃,即使我先调用了Py_SetProgramName并传入"c:\python27\python27.exe"

我希望能在VB/VBA中指定安装路径,而不是依赖环境变量,因为我在Excel中无法这样做(在VB6中可以正常工作)。

3 个回答

0

你可以简单地检查一下所需的环境变量是否已经设置:

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

或者你可以在另一个测试进程中运行这个dll:如果这个调用成功了,那就说明可以安全地调用这个dll。不过这还要看你使用的dll调用方式,所以我不太确定这一点:

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

祝好,托马斯

1

试着在调用dll之前先改变工作目录:

在你的VBA代码中:

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?!)

祝好,托马斯

3

我找到的最好的答案是,这在Python里算是一个bug - http://bugs.python.org/issue6498。当出现某些错误时,解释器似乎会直接调用exit(),而不是把错误代码返回给调用者。如果你把Python嵌入到一个应用程序里,这样做就不太友好了。不过就是这样。

撰写回答