[IronPython] How I got IronPython scripting to run in C++/cli
L. Lee Saunders
saunderl at hotmail.com
Fri Mar 4 21:24:06 CET 2011
It seems like such a simple set of code now ... but when I was banging my
head trying to get it to work, well, that is a different story.
This function is called after FastCAD (the engine under the hood of
profantasy's Campaign Cartographer 3) runs a method that asks the user for a
script file (PythonCmd). FastCAD places the name of the file in txtFileName
as a char[].
All the SetVariables setup C++/cli classes that I use to expose FastCADs
API. From here I work through delegates so that I never have to discover
functions in IronPython. I could not figure out how to do that in C++/cli
3.5. It seems easy in 4.0 with the dynamic type, but Campaign Cartographer
3s installer currently only loads the C++ 3.5 runtimes.
///////////////////////////////////////////////////////////////////////
void XPCALL PythonCmd2(int Result, int Result1, int Result2) {
if(Result==X_OK)
{
try
{
String^ filename = gcnew String(txtFileName);
String^ path = Assembly::GetExecutingAssembly()->Location;
ScriptEngine^ engine = Python::CreateEngine();
ScriptScope^ scope = engine->CreateScope();
ScriptSource^ source =
engine->CreateScriptSourceFromFile(String::Concat(Path::GetDirectoryName(pat
h), "\\scripts\\ <file:///\\scripts\> ", filename + ".py"));
scope->SetVariable("DrawingList",
DynamicHelpers::GetPythonTypeFromType(AddIn::DrawingList::typeid));
scope->SetVariable("DrawingElement",
DynamicHelpers::GetPythonTypeFromType(AddIn::DrawingElement::typeid));
scope->SetVariable("DrawingPath",
DynamicHelpers::GetPythonTypeFromType(AddIn::DrawingPath::typeid));
scope->SetVariable("Node",
DynamicHelpers::GetPythonTypeFromType(AddIn::Node::typeid));
source->Execute(scope);
}
catch(Exception ^e)
{
Console::WriteLine(e->ToString());
CmdEnd();
}
}
else
{
CmdEnd();
}
}
////////////////////////////////////////////////////////////////////////////
///
Here is an example ipy script that draws a diamond at the selected point.
When the C++/cli soure->Execute(scope) line is called, the only python line
to run is the DrawingList.RequestData.
RequestData takes a delegate and a data type.
When the C++/cli code is done, it calls the delegate pointing to the
function "diamond"
In the function diamond it retrieves the requested data with the call to
DrawingList.RequestedValue() The call to DrawingList.AddElement(dp) adds the
new element to the FastCAD visual Database.
And lastly the call to DrawingList.EndCommand() tells the FastCAD engine to
clean up and end the running of the plugin.
import clr
def diamond(Result1, Result2, Result3):
if(Result1 == 0):
dp = DrawingPath()
dp.drawingStuff.EntityColor = 2
dp.drawingStuff.SecondEntityColor = 2
n = DrawingList.RequestedValue()
dp.Nodes.Add(Node(n.X-50,n.Y+25))
dp.Nodes.Add(Node(n.X-25,n.Y+50))
dp.Nodes.Add(Node(n.X+25,n.Y+50))
dp.Nodes.Add(Node(n.X+50,n.Y+25))
dp.Nodes.Add(Node(n.X,n.Y-40))
DrawingList.AddElement(dp)
DrawingList.EndCommand()
DrawingList.RequestData(diamond, DrawingList.RequestType.PointType)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/ironpython-users/attachments/20110304/ef7b54be/attachment.html>
More information about the Ironpython-users
mailing list