VB6 Python embed w/debugger


Author: Dave
Date: 09.04.23 - 2:35am



Downloads: Installer, Source

So in the last post we had an example of python embedding within C.

C is not my main language, so it was only natural that the next step was to take it into the vb realm which is exactly what happened.

We have talked about integrating with python before. So in todays episode we do it embedded style.

The example linked above is my initial experiments with it. Current features in this sample:
  • set script command line arguments
  • manually import modules
  • manually set global script values
  • hook the python output to stdout (print) and stdErr
  • run a python script in memory from its text string
  • call a python function with an argument
  • receive the function return value
  • read a global variable/global obj property from the script
  • hook exit, sys.exit, and quit so they dont close the process.
  • interact with VB COM objects (pywin32lib)
  • threading example
  • python debugger example
    • single step, breakpoints, call stack, step out, set next line, inspect globals/locals/args, modify variable
    • Note: current UI does not yet have intellisense and I am just letting it use the java hilighter for now
The debugger example is the most fun. Python makes this ridiculously easy compared to what I have had to go through in the past.

I guess this is the 6th interactive debugger I have written. (x86, scdbg, Scriptbasic, duktape, pcode)



Python is kinda like eating candy, and also probably not good for your teeth. Interoperability and library wise, apparently we just need it. To many code monkeys churning out stuff, just cant deny it.

So anyway, being able to call fragments of code and utilize libraries from it is a force multiplier. To embed it in vb6 we will need the 32 bit version. I linked against Python 3.11

The python debug/trace api actually runs from within the script itself which is interesting.

Python embedding seems to be slightly a second class citizen. They generally think of everything (its mature at this point).
  • pywin32 extension doesnt really support embedding. Cant call finalize if you want it to work a second time.
  • I havent found an end script api yet. exit and quit want to close the process without hooking.
  • raise keyboard interrupt to end can be masked with while 1 try except. Not sure how to end the script in every context yet.
Overall though, implementing the basic debugger UI with most features was done in a half days labor which is crazy. (I did rip code from duk4vb though and was already familiar with scintilla from previous war campaigns)

Anyway, there is still more to come. I started a thread on it over at vbforums. The example linked above will be updated more regularly than the forum copy.

This will probably end up as an ocx soon where I can call small python scripts in memory directly from vb6, reuse existing libraries I have to be compatiable with (or just no code myself), and the IDE / Debugger portion will be perfect for extending my own apps and using it for user automation.

Will see how it all shakes out.

Todo:
  • find proper end script now call with no loopholes.
  • rip pywin32 IDispatch code and integrate into py4vb.dll so I can finalize.
  • use python lexer and highlighter
  • intellisense & obj browser
  • review for memory leaks (Py_DecRef)
  • ???





Comments: (3)

On 09.12.23 - 7:20am Dave wrote:
Stripping down pywin32 to include just the IDispatch stuff in my own dll. Pywin32 is pretty huge and covers a zillion things. Much over my head. Have a minimal build compiling now.

Stepping through the python side is complicated too. It’s robust code, performance optimized. Interesting design.

Dumb dispatch for no type info. It brute forces methods to see what call type works, then dynamically builds a function definition, compiles and evals it into scope for python access. It’s then cached as a performance optimization.

The initial dynamic lookup triggers from the __getattr__ dunder voodoo to dynamically catch arbitrary access on demand.

It’s impressive, I may be able to do the same thing with duktape and a js proxyclass. I was pre building class wrappers from source parsing. In the full version he does that too but from typelibs.

It’s frying my noodle a bit. Complicated but not unapproachable . So far so good!

As for why, removing the dependency on pywin32 will allow me to call Py_Finalize again and start each script fresh. Plus since I am working all within process, integrating more tightly with it, I should be able to use my in memory live COM objects directly rather than having to work through the ROT.

Just tightening things up for my use case.

On 09.17.23 - 7:19pm Dave wrote:
Took me maybe 3 days to get the COM bits of pywin32 extracted and implemented into my helper dll. Seems to be working. pycom.GetObject will now first check for a vb host shared object before trying the ROT.

see com_internal_example. Note: you will have to copy pycom folder to your python /lib/site-packages directory manually.

On 10.22.23 - 5:30pm Dave wrote:
There is now an installer that busked everything together in an easy to use ocx packsge. Comes with a full python 311 install, ocx conttols fir python and debugger, and the custom dlls and python package already installed. You will still need the mscomctl but since your likely a vb6 developer already that’s not a problem.

 
Leave Comment:
Name:
Email: (not shown)
Message: (Required)
Math Question: 65 + 91 = ? followed by the letter: C 



About Me
More Blogs
Main Site
Posts: (All)
2024 ( 3 )
2023 (9)
     VB6 Virtual Files
     File handles across dlls
     python abort / script timeout
     py4vb
     VB6 Python embed w/debugger
     python embedding
     VB6 IDE Enhancements
     No Sleep
     A2W no ATL
2022 (4)
     More VB6 - C data passing
     Vb6 Asm listing
     Byte Array C to VB6
     Planet Source Code DVDs
2021 (2)
     Obscure VB
     VB6 IDE SP6
2020 ( 4 )
2019 ( 5 )
2018 ( 6 )
2017 ( 6 )
2016 ( 22 )
2015 ( 15 )
2014 ( 25 )
2013 ( 4 )
2012 ( 10 )
2011 ( 7 )
2010 ( 11 )
2009 ( 3 )