C++与IronPython集成示例代码?
我在找一个简单的示例代码,用于C++和IronPython的结合,也就是在C++程序里嵌入Python代码,或者更好的是在Visual C++程序中嵌入。
这个示例代码应该包括:如何在这两种语言之间共享对象,如何相互调用函数或方法等等……
另外,明确的设置步骤也会很有帮助。(比如,如何在Visual Studio中包含Python运行时的dll文件等等……)
我找到了一些关于C#和IronPython的不错示例,在这里,但找不到C++和IronPython的示例代码。
2 个回答
如果你不需要.NET的功能,可以考虑直接嵌入Python,而不是使用IronPython。想了解更多信息和示例,可以查看Python的文档,里面有关于在其他应用程序中嵌入Python的内容。如果你不介意依赖BOOST,可以试试它的Python集成库。
更新 - 我在我的博客上写了一个更通用的例子(还有一个包含整个VS2008项目的压缩文件链接),可以在这里找到。
抱歉,我来得有点晚,但我想分享一下我是如何在Visual Studio 2008中将IronPython集成到一个C++/cli应用里的,这个应用是基于.net 3.5的。(实际上是一个混合模式的应用,包含C/C++)
我为一个用汇编语言写的地图制作应用程序编写插件。这个应用的API是开放的,所以可以用C/C++来写插件。我把C/C++和C++/cli混合使用。这个例子中的一些元素来自于API(比如XPCALL和CmdEnd() - 请忽略它们)。
///////////////////////////////////////////////////////////////////////
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(path), "\\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();
}
}
///////////////////////////////////////////////////////////////////////////////
如你所见,我向IronPython暴露了一些对象(DrawingList、DrawingElement、DrawingPath和Node)。这些对象是我创建的C++/cli对象,用来向IronPython提供“东西”。
当调用C++/cli的source->Execute(scope)这一行时,唯一要运行的Python代码是DrawingList.RequestData。
RequestData需要一个委托和一个数据类型。
当C++/cli代码完成后,它会调用指向“diamond”函数的委托。
在“diamond”函数中,它通过调用DrawingList.RequestedValue()来获取请求的数据。接着,调用DrawingList.AddElement(dp)将新元素添加到应用程序的可视数据库中。
最后,调用DrawingList.EndCommand()告诉FastCAD引擎清理并结束插件的运行。
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)
希望这正是你想要的内容。