开发者

How do I stop Py_Initialise crashing the application?

开发者 https://www.devze.com 2023-04-08 11:07 出处:网络
From VBA and VB6 I\'m calling a dll the creates a Python 开发者_运维知识库interpreter. If I set the PATH environment variable to point to \"C:\\python27\" and PYTHONPATH to \"c:\\python27\\lib\" all i

From VBA and VB6 I'm calling a dll the creates a Python 开发者_运维知识库interpreter. If I set the PATH environment variable to point to "C:\python27" and PYTHONPATH to "c:\python27\lib" all is fine.

If I don't set the PATH then calling Py_Initialise() crashes XL or my VB6 app, even if I call Py_SetProgramName with "c:\python27\python27.exe" first.

I'd like to specify the installation in VB/VBA rather than having it set in the environment as I can't do that in XL (works ok for VB6).


The best answer I've found so far is that it is a bug in Python - http://bugs.python.org/issue6498. The intepreter seems to call exit() on certain errors rather than passing a code back to the caller. Not very friendly if you're embedding python in an app. But there you go.


try to change the working directory before calling the dll:

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

regards Thomas


You can simply check if the needed environment variable is set:

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

Or you can run the dll in a nother Test-Process: if this call works you know that it is OK to call the dll - it depends on the DLL call your using so I'm not sure about that:

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

Regards Thomas

0

精彩评论

暂无评论...
验证码 换一张
取 消