如何在不创建MODU的情况下将C++类暴露到Python

2024-10-01 13:36:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我想知道是否有任何方法将C++类暴露给Python,但不需要构建中间共享库。在

这是我想要的情景。例如,我有以下C++类:

class toto
     {
     public:
        toto(int iValue1_, int iValue2_): iValue1(iValue1_), iValue2(iValue2_) {}
        int Addition(void) const {if (!this) return 0; return iValue1 + iValue2;}

      private:
        int iValue1;
        int iValue2;
     };

我想以某种方式将这个类(或它的存在)转换为PyObject*,以便将它作为paremter(args)发送到例如PyObject_CallObject:

^{pr2}$

另一方面,在我的Python端,我将有一个RePabPrime'函数,它将指针放在C++类(或它的实例)上作为参数,调用它的方法或使用其属性:

def wrapper_function(cPlusPlusClass):
    instance = cPlusPlusClass(4, 5)
    result = instance.Addition()

正如您所看到的,我并不需要/不想拥有单独的共享库或使用boostpython构建模块。我需要的是找到一种方法来将C++代码转换为PyObject并将其发送到Python。我无法通过C python库boost或SWIG来实现这一点。在

你知道吗? 谢谢你的帮助。在


Tags: 方法instancereturnifpublicclassintpyobject
2条回答

据我所知,要做到这一点没有一个简单的方法。在

用C++既不带模块也不使用中间库来扩展Python,则需要动态加载库,然后导入函数。此方法由^{}模块使用。为了实现C++的相同,需要编写一个^ { } i> >,以了解目标编译器的C++ abi。在

< P>在不引入模块的情况下,扩展Python,可以创建一个中间的库,它提供了一个C C++ API来封装C++库。然后可以通过ctypes在Python中使用这个中间库。虽然它不提供精确的调用语法,并且引入中间库,但它可能比构建一个可以与C++直接接口的^ {CD1> } i>类的库要少得多。在

但是,如果要引入一个中间库,它可能是值得使用的Boost.Python,SWIG,或其他一些C++ + Python语言绑定工具。虽然这些工具中的许多都将通过模块引入扩展,但它们通常提供更干净的调用约定,在绑定过程中更好地进行错误检查,并且可能更易于维护。在

我找到了答案。实际上,我搜索的内容与此答案非常相似(感谢Mooeeep的评论):

Exposing a C++ class instance to a python embedded interpreter

遵循C++类(注意!默认构造函数是必需的):

class TwoValues
{
public:
    TwoValues(void): iValue1(0), iValue2(0) {}
    TwoValues(int iValue1, int iValue2): iValue1(iValue1_), iValue2(iValue2_) {}

    int Addition(void) const {if (!this) return 0; return iValue1 + iValue2;}

public:
    int iValue1;
    int iValue2;
};

可以通过以下宏通过boost暴露:

^{2}$

另一方面,我有一个在python_script.py中定义的python函数,它获取这个类的一个实例并做一些事情。例如:

def wrapper_function(instance):
    result = instance.Addition()
    myfile = open(r"C:\...\testboostexample.txt", "w")
    output = 'First variable is {0}, second variable is {1} and finally the addition is {2}'.format(instance.Value1, instance.Value2, result)
    myfile .write(output)
    myfile .close()

然后,在C++侧,我可以通过同时发送类的实例来调用这个函数,例如:

Py_Initialize();

try
    {
    TwoValues instance(5, 10);
    initModuleTestBoost();

    object python_script = import("python_script");
    object wrapper_function = python_script.attr("wrapper_function");
    wrapper_function(&instance);
    }
catch (error_already_set)
    {
    PyErr_Print();
    }

Py_Finalize();

优点:

  • 我不需要构建任何共享库或二进制文件
  • 当我使用Boost时,我不需要担心内存管理 &引用计数(amp;R)
  • 我不使用共享的boost指针(boost::shared\ptr)来指向 我的类的实例

相关问题 更多 >