Python and VB6
Date: 11.09.17 - 6:01am
Ok..so there are a ton of python libraries out there I dont want to immediately port over to vb6. How do we communicate between python code and vb6?
Let me start by saying part of me hates this because its pretty hackish and requires dependencies and moons in alignment with packages etc. So this is just for one offs, at present I would never distribute code that ran like this, but with that said I may still need to do it to accomplish a research goal.
So here are our options as I see it so far:
I was pleased to see python had support for COM, and it seems to work ok...but it also took a bit of fussing and fighting to get it going. Here are some tips on vb6 and Python over COM
In the end I was able to get the following demos working:
- just run a command line script and consume its output (file or stdout)
- use IPC (Could be in process or out of process)
- COM and/or Addressof Callbacks
- embedding python and using the python intrepreter dll
Those were the first major tests I could think of to get my feet wet.
The process and debugging seems a little delicate and hairy with nuances and poor debugging experience.
- IPC out of process demo using WM_COPYDATA
- CreateObject of a python COM object from VB6
- python function taking in a string and returning a variant array
- python calling a vb6 addressof callback and passing in a string and int
- python returning a new instance of a vb6 usable python COM object
- get/set a property on a python COM object
- pass VB COM object to python and:
- python calls sub on vb object
- python does property get to get object reference for form1.Text1
- python does property get for form1.Text1.Text
The IPC went smoothly and of course the stdout/file out will go smooth.
As for embedding python and using it from vb6 directly as the dll. This was my first thought on the way to go and I may play with it, but it will be the most work. The python dll is not stdcall so we will need a C shim to access its api and provide wrappers. This is probably the only way I would consider this technique for distribution with an app because I could control the environment.
*BugFix for cached classes:
So apparently it is by design that once a class is loaded in a process it is cached and changes to the file do not take effect until the module is manually reloaded or the you get a new process.
For our test code this matters while working in the vb6 IDE since we are doing development work and probably want to edit the python source but are always calling it from the same IDE process instance.
So here is the fix..
In the python class we add an exec method:
def Exec(self, exp):
"""Execute a statement.
if type(exp) not in [str, unicode]:
raise Exception(desc="Must be a string",scode=winerror.DISP_E_TYPEMISMATCH)
exec str(exp) in self.dict
Then in VB we can add the following code:
If IsIde() And GetModuleHandle("python27.dll") <> 0 Then
dbg "found python in memory still..trying to reload module in case there were changes..."
Function reload(moduleName As String) As String
On Error Resume Next
Dim cmd As String
cmd = Replace("import %1;reload(%1)", "%1", moduleName)
Set o = CreateObject("PythonDemos.Utilities")
Text1 = Replace(Err.Description, vbLf, vbCrLf)