Sac*_*cha 5 c++ python swig boost-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;
};
Run Code Online (Sandbox Code Playgroud)
我想以某种方式将此类(或其intance)转换为PyObject*,以便将其作为paremter(args)发送到例如PyObject_CallObject:
PyObject* PyObject_CallObject(PyObject* wrapperFunction, PyObject* args)
Run Code Online (Sandbox Code Playgroud)
另一方面,在我的python方面,我将有一个wrapperFunction,它将我的C++类(或其实例)上的指针作为参数获取,并调用其方法或使用其属性:
def wrapper_function(cPlusPlusClass):
instance = cPlusPlusClass(4, 5)
result = instance.Addition()
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我并不需要/希望拥有单独的共享库或通过boost python构建模块.我需要的只是找到一种方法将C++代码转换为PyObject并将其发送到python.我无法通过C python库,boost或SWIG找到一种方法.
你有什么主意吗?谢谢你的帮助.
据我所知,没有简单的方法来实现这一目标.
要使用C++扩展Python既不是模块也不是中间库,它需要动态加载库,然后导入函数.该方法由ctypes模块使用.要用C++实现同样的目标,需要编写一个ctypes类似于目标编译器的C++ ABI的库.
为了在不引入模块的情况下扩展Python,可以创建一个中间库,它提供了一个包装C++库的C API.然后可以在Python中使用此中间库ctypes.虽然它没有提供确切的调用语法并且确实引入了一个中间库,但它可能比构建一个可以直接与C++接口ctypes的类库一样省力.
但是,如果要引入中间库,则可能值得使用Boost.Python,SWIG或其他一些C++/Python语言绑定工具.虽然其中许多工具将通过模块引入扩展,但它们通常提供更清晰的调用约定,更好的绑定过程中的错误检查,并且可能更容易维护.
我找到了答案。实际上我正在搜索的内容与这个答案非常相似(感谢 moooeeeep 的评论):
\n\n\xc2\xa0将 C++ 类实例公开给 python 嵌入式解释器
\n\n以下 C++ 类(注意!默认构造函数是强制性的):
\n\nclass TwoValues\n{\npublic:\n TwoValues(void): iValue1(0), iValue2(0) {}\n TwoValues(int iValue1, int iValue2): iValue1(iValue1_), iValue2(iValue2_) {}\n\n int Addition(void) const {if (!this) return 0; return iValue1 + iValue2;}\n\npublic:\n int iValue1;\n int iValue2;\n};\nRun Code Online (Sandbox Code Playgroud)\n\n可以通过以下宏来通过 boost 来暴露:
\n\nBOOST_PYTHON_MODULE(ModuleTestBoost)\n{\nclass_<TwoValues>("TwoValues")\n .def("Addition", &TWOVALUES::Addition)\n .add_property("Value1", &TWOVALUES::iValue1)\n .add_property("Value2", &TWOVALUES::iValue2);\n};\nRun Code Online (Sandbox Code Playgroud)\n\n另一方面,我定义了一个 python 函数,其中python_script.py获取此类的实例并执行某些操作。例如:
def wrapper_function(instance):\n result = instance.Addition()\n myfile = open(r"C:\\...\\testboostexample.txt", "w")\n output = \'First variable is {0}, second variable is {1} and finally the addition is {2}\'.format(instance.Value1, instance.Value2, result)\n myfile .write(output)\n myfile .close()\nRun Code Online (Sandbox Code Playgroud)\n\n然后在 C++ 端,我可以通过同时发送类的实例来调用此函数,如下所示:
\n\nPy_Initialize();\n\ntry\n {\n TwoValues instance(5, 10);\n initModuleTestBoost();\n\n object python_script = import("python_script");\n object wrapper_function = python_script.attr("wrapper_function");\n wrapper_function(&instance);\n }\ncatch (error_already_set)\n {\n PyErr_Print();\n }\n\nPy_Finalize();\nRun Code Online (Sandbox Code Playgroud)\n\n优点:
\n\n