How much begging, prodding, crying and worshipping would it take to get Python added to the list of supported scripting languages?
I don't know what interface you're using, but if its the ActiveX/Windows Scripting Host, then Python interfaces to it just fine with the win32all package...
I tried that - the appropriate changes are in the code, however it didn't work. Some bizarre interface problem. Unless they have fixed up the Python script interface I can't do it.
// pScriptEngine = new CScriptEngine (this, "vbscript"); // this works
pScriptEngine = new CScriptEngine (this, "python"); // this doesn't
If you change the language to "vbscript" then it works and displays the message box. Otherwise you get the message about the ESP value. If you comment out the line that adds the "world" variable to the script engine it crashes anyway (scripttengine.cpp line 210).
The files are largely unchanged from the MUSHclient version, in the stdafx.h file is a define:
#define CMUSHclientDoc CScripttestDoc
This is so that the files think it is using a CMUSHclientDoc document.
If you can get this to work (changing compile options or something?) then I should be able to make MUSHclient work too.
I don't know about this "declared with a different calling convention" bit - the exact same code works if you change the language to Vbscript, Jscript, or Perlscript.
Hmm. Did a bit of hunting and found that most things dealing with Python and 'calling convention' involve the facts that Python and C++ do not automatically use the same method. While my brief search didn't uncover specifics, one possibility is that Python uses the Pascal convention and in that case the difference involves stack management. The method C++ uses is 'caller clears the stack', while the pascal method employs 'the program called clears the stack'. This is only a guess though, but it suggests that a key process is either being done by both ends or by neither end and this would definitely cause a crash.
Wish I knew if this was the case or how to actually fix it though.. I imagine that changing the calling method to properly support Python could break everything else, so there has to be some sort of better solution. :p
After making a subtle change to the way scripting was instantiated - after spending hours reading web pages - I now have Python active (nothing to do with calling conventions BTW). However after a script error in "immediate" mode it stops processing further scripts. I am investigating this.
Meanwhile, as a newbie to Python, perhaps a few examples of the sort of thing you would like to try would help me to test it.
Here is a simple example. In the plugins I echo the description by getting plugininfo, which is a variant, and displaying it with Note, which takes a string. Like this:
Can you suggest the syntax (for one line, I can work out the rest) for the constant list? This is auto-generated by the page anyway, I just need the format to do it.
*laugh* Mark, you answer your own questions faster then I can even think about trying to pretend to answer them. The only question I see that you don't appear to have answered yourself is the constants list. There is no conception of 'constant' in python, although I can build a class to do it for you rather easily. Its unnessecary though, really... Just spit out a list of variables.
eOK = 0 # No Error
eWorldOpen = 30001 # The world is already open.
..etc... that's it.. Python is very not-force-you-to-obey-the-rules. Python programmers do what they're supposed to without it. :)
I misspelt it, it is GetInternalCommandsList, not GetInternalCommandList, however my example worked apart from that.
Adding the brackets stops it working, however GetInternalCommandsList is a function returning a variant array, not an actual array.
for cmd in world.GetInternalCommandsList: world.Note (cmd)
If I add the brackets I get the error "'tuple' object is not callable".
The only remaining problem seems to be that the script engine doesn't seem to support "global" members. so I need to explicitly use world.X whereas in the other languages I can omit "world." which I am starting to do in recent examples. Unless you know a way of working around that, eg. something like the old Pascal syntax:
In case someone is searching the Net for this one day, here is how I fixed it.
The error message was:
"The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."
Module: chkesp.c line 42
The solution was to change the CoCreateInstance call slightly. No change was made to calling conventions.
The only way I can think of to achieve that global members issue, is for you to do:
import __builtin__
__builtin__.Note = world.Note
... for each of the functions. A short cut that may or may not work is:
__builtin__.__dict__.update(world.__dict__)
If 'world' doesn't have a dictionary, this won't work... I dont know how these activex objects work in python internally. If it does work it'll copy world's dictionary into the global namespace. __dict__ is an associative array that represents a perticular namespace, essentially.
I *personally* think this is a bad idea and that everything should be 'world.Note' etc... Standard pythonism is 'explicit is better then implicit' :)
I only asked because I was starting to get used to the way VBscript lets me get away without typing "world." all the time.
I am about ready to release the Python-compatible version, if you look at the scripting functions pages you see there is now an entry for the Python example for each script function.