这个问题是关于如何将一个C++对象传递给在(C++)嵌入式Python解释器中调用的Python函数的。
下面的C++类(MyClass.h)是为了测试而设计的:
#ifndef MyClassH
#define MyClassH
#include <string>
using std::string;
class MyClass
{
public:
MyClass(const string& lbl): label(lbl) {}
~MyClass(){}
string getLabel() {return label;}
private:
string label;
};
#endif
以下Swig接口文件可以生成一个暴露C++类的Python模块:
%module passmetopython
%{ #include "MyClass.h" %}
%include "std_string.i"
//Expose to Python
%include "MyClass.h"
以下是使用Python模块的Python脚本
import passmetopython as pmtp
def execute(obj):
#This function is to be called from C/C++, with a
#MyClass object as an argument
print ("Entering execute function")
lbl = obj.getLabel();
print ("Printing from within python execute function. Object label is: " + lbl)
return True
def main():
c = pmtp.MyClass("Test 1")
retValue = execute(c)
print("Return value: " + str(retValue))
#Test function from within python
if __name__ == '__main__':
main()
这个问题是关于如何在从C++中调用Python的execute()函数,并将一个C++对象作为参数进行传递。
下面的C++程序旨在测试这些函数(仅包含最少量的错误检查):
#include "Python.h"
#include <iostream>
#include <sstream>
#include "MyClass.h"
using namespace std;
int main()
{
MyClass obj("In C++");
cout << "Object label: \"" << obj.getLabel() << "\"" << endl;
//Setup the Python interpreter and eventually call the execute function in the
//demo python script
Py_Initialize();
//Load python Demo script, "passmetopythonDemo.py"
string PyModule("passmetopythonDemo");
PyObject* pm = PyUnicode_DecodeFSDefault(PyModule.c_str());
PyRun_SimpleString("import sys");
stringstream cmd;
cmd << "sys.path.append(\"" << "." << "\")";
PyRun_SimpleString(cmd.str().c_str());
PyObject* PyModuleP = PyImport_Import(pm);
Py_DECREF(pm);
//Now create PyObjects for the Python functions that we want to call
PyObject* pFunc = PyObject_GetAttrString(PyModuleP, "execute");
if(pFunc)
{
//Setup argument
PyObject* pArgs = PyTuple_New(1);
//Construct a PyObject* from long
PyObject* pObj(NULL);
/* My current attempt to create avalid argument to Python */
pObj = PyLong_FromLong((long) &obj);
PyTuple_SetItem(pArgs, 0, pObj);
/***** Calling python here *****/
cout<<endl<<"Calling function with an MyClass argument\n\n";
PyObject* res = PyObject_CallObject(pFunc, pArgs);
if(!res)
{
cerr << "Failed calling function..";
}
}
return 0;
}
当运行上述代码时,execute() Python函数使用一个MyClass对象作为参数失败并返回NULL。但是,Python函数已经被调用,因为我可以在控制台输出中看到输出(Entering execute function),这表明传递的对象确实不是一个有效的MyClass对象。有很多关于如何从C/C++传递简单类型(如int、double或字符串类型)到Python的例子。但是很少有例子展示如何传递C/C++对象/指针,这有点令人困惑。
上述代码及其CMake文件可以从GitHub检出: https://github.com/TotteKarlsson/miniprojects/tree/master/passMeToPython 此代码不使用任何boost python或其他API。但Cython听起来很有趣,如果它可以用于简化C++端,那么它可能是可接受的。
pFunc
对象。它不是这样工作的。myObject
必须是一个有效的PyObject
(我认为它不是 - 直到我看到MyObject
的定义,我不能确定)。“C++类已经使用swig进行了封装”:那么我认为你不需要编写这个C代码。 - CristiFati