我该如何停止 Py_Initialise 导致应用程序崩溃?

4
从VBA和VB6调用一个创建Python解释器的DLL。如果我设置PATH环境变量指向"C:\python27"PYTHONPATH指向"c:\python27\lib",一切正常。
如果我没有设置PATH,那么调用Py_Initialise()会使XL或我的VB6应用程序崩溃,即使我先调用Py_SetProgramName并使用"c:\python27\python27.exe"
我想在VB/VBA中指定安装位置,而不是在环境中设置,因为我无法在XL中这样做(对于VB6可以正常工作)。

甚至可以检查配置是否有效的方法也是好的。最坏的情况下,我可以使用 getenv 或 GetEvvironmentVariable(我在 windows 上)设置环境变量。我想链接到安装的 python 副本,而不会损坏 excel 或任何其他嵌入 python 的应用程序。 - DangerMouse
3个回答

3
我目前找到的最佳答案是,这是 Python 中的一个 bug - http://bugs.python.org/issue6498。解释器似乎在某些错误情况下调用 exit() 而不是将代码返回给调用方。如果你想在应用程序中嵌入 Python,则不太友好。但是就是这样。

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

敬礼,Thomas


1
并没有真正解决 Py_Initialise 导致应用程序崩溃的问题。 - DangerMouse
1
更糟糕的是,这个程序将绑定在安装有Python 2.7标准位置的Windows机器上。 - Fred Foo
应用程序崩溃的原因是[Py_Initialise]找不到某些文件夹或文件?!因此,如果您更改到[Py_Initialise]搜索文件/文件夹的文件夹,它将不会崩溃-希望如此。[larsmans]我使用这个路径是因为它在问题中提到...?!这个答案只是给出了大致的想法,您需要做什么。 - Thomas
@Thomas,虽然这可能是一个好建议,但它并没有回答问题。正如我在问题中所指出的那样,我可以正确地设置。我正在尝试弄清楚如何阻止Py_Initialize在设置不正确时终止主机进程-我更喜欢一个漂亮的对话框告诉用户问题所在。 - DangerMouse

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

致敬,托马斯


是的,我正在考虑运行一个测试过程来检查设置是否正常。不是特别热衷于这个,但如果没有其他方法可以防止Py_Initialise崩溃它的主机,那么这可能是答案。谢谢。 - DangerMouse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接