C++与IronPython集成示例代码?

5 投票
2 回答
2828 浏览
提问于 2025-04-16 05:38

我在找一个简单的示例代码,用于C++和IronPython的结合,也就是在C++程序里嵌入Python代码,或者更好的是在Visual C++程序中嵌入。

这个示例代码应该包括:如何在这两种语言之间共享对象,如何相互调用函数或方法等等……

另外,明确的设置步骤也会很有帮助。(比如,如何在Visual Studio中包含Python运行时的dll文件等等……)

我找到了一些关于C#和IronPython的不错示例,在这里,但找不到C++和IronPython的示例代码。

2 个回答

1

如果你不需要.NET的功能,可以考虑直接嵌入Python,而不是使用IronPython。想了解更多信息和示例,可以查看Python的文档,里面有关于在其他应用程序中嵌入Python的内容。如果你不介意依赖BOOST,可以试试它的Python集成库

2

更新 - 我在我的博客上写了一个更通用的例子(还有一个包含整个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)

希望这正是你想要的内容。

撰写回答