【问题标题】:How do I stop Py_Initialise crashing the application?如何阻止 Py_Initialise 使应用程序崩溃?
【发布时间】:2011-09-27 06:26:20
【问题描述】:

我从 VBA 和 VB6 调用 dll 来创建 Python 解释器。如果我将PATH 环境变量设置为指向"C:\python27"PYTHONPATH 指向"c:\python27\lib",一切都很好。

如果我没有设置 PATH,那么调用 Py_Initialise() 会导致 XL 或我的 VB6 应用程序崩溃,即使我先使用 "c:\python27\python27.exe" 调用 Py_SetProgramName

我想在 VB/VBA 中指定安装,而不是在环境中设置,因为我无法在 XL 中执行此操作(适用于 VB6)。

【问题讨论】:

  • 即使以某种方式检查配置是否有效。在最坏的情况下,我可以使用 getenv 或 GetEvvironmentVariable 设置环境变量(我在 Windows 上)。我想链接到 python 的安装副本,而不是炸毁 excel 或任何其他 python 嵌入器。

标签: c++ python excel vba vb6


【解决方案1】:

到目前为止,我发现的最佳答案是它是 Python 中的一个错误 - http://bugs.python.org/issue6498。解释器似乎在某些错误上调用 exit() 而不是将代码传回给调用者。如果您在应用程序中嵌入 python,则不是很友好。但是你去吧。

【讨论】:

    【解决方案2】:

    在调用 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?!)
    

    问候托马斯

    【讨论】:

    • 并没有真正解决 Py_Initialise 使应用程序崩溃的问题。
    • 更糟糕的是,将程序与安装了 Python 2.7 的 Windows 机器绑定在硬盘 C 上的标准位置。
    • 应用程序崩溃是因为 [Py_Initialise] 没有找到某个文件夹或文件?!因此,如果您更改为 [Py_Initialise] 搜索文件/文件夹的文件夹,它不会崩溃 - 希望如此。 [larsmans] 我使用这条路径是因为问题中提到了它......?!这个答案只给出了你必须做什么的粗略想法。
    • @Thomas,虽然这可能是个好建议,但它并不能回答问题。如我的问题所示,我可以正确设置。如果设置不正确,我正在尝试弄清楚如何阻止 Py_Initialize 终止主机进程 - 我希望有一个漂亮的对话框告诉用户问题。
    【解决方案3】:

    您可以简单地检查是否设置了所需的环境变量:

    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 使其主机崩溃,那么这可能就是答案。谢谢。
    猜你喜欢
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-08
    • 2015-01-28
    • 1970-01-01
    • 2012-06-04
    相关资源
    最近更新 更多