Google了很多資料,找到的都不滿意,于是摸索許久后有了些發現。
以下只是對自己摸索結果的總結,其中難免存在錯誤,
如有任何錯誤,望不惜指正類定義:
class Demo
{
private:
int m_val;
string m_nam;
public:
void setVal(int val)
{
m_val = val;
}
int getVal()
{
return m_val;
}
void setName(const char *name)
{
m_nam = name;
}
const char* getName()
{
return m_nam.c_str();
}
void show()
{
std::cout <<"hello world" <<std::endl;
}
};
方法一:void fun1()
{
Py_Initialize();
PyObject *pModule = PyImport_ImportModule("helloworld");
handle<>_module(pModule);
object main_module(_module);
// 導出C++類到python中
main_module.attr("Demo") = class_ <Demo>("Demo") // 通過boost::python中的class_將C++類包裝成object類型,因為python中所有類型都是object
.def("setVal", &Demo::setVal)
.def("setName", &Demo::setName)
;
// 通過boost::python提供的模板函數ptr,來將Demo對象傳入python
Demo a;
main_module.attr("test") = object(ptr(&a));
std::cout <<"之前:"<< a.getName() << " " << a.getVal()<<endl;
call_method<void>(pModule , "fun2");
std::cout <<"之后:"<< a.getName() << " " << a.getVal()<<endl;
// 通過python函數返回C++對象
Demo tmp = call_method<Demo>(pModule , "ReturnCppClass");
std::cout << tmp.getName() << " " << tmp.getVal() <<endl;
} helloworld.py腳本內容:
def fun2():
tmp = test;
tmp.setVal(12345);
tmp.setName("2011-5-19");
def ReturnCppClass():
tmp = Demo();
tmp.setName('123456789')
tmp.setVal(99);
return tmp;
1.語句main_module.attr("test") = object(ptr(&a)); 中的"test"是a對象在腳本中的別名,于是腳本中可以直接通過test名字操作C++對象。
2.Demo tmp = call_method<Demo>(pModule , "ReturnCppClass");來實現在python中創建C++對象,并且返回到C++中
方法二:
通過智能指針實現C++對象的導入
typedef boost::shared_ptr < Demo > Demo_ptr;
void fun2()
{
Py_Initialize();
Demo_ptr spD1(new Demo);
spD1->setName("NULL");
spD1->setVal(0);
try
{
PyObject *pModule = PyImport_ImportModule("helloworld");
register_ptr_to_python <Demo_ptr>(); // 注冊只能指針
handle<>* _module;
_module = new handle<>(pModule);
object main_module(*_module);
object dictionary = main_module.attr("__dict__");
dictionary["Demo"] = class_ <Demo>("Demo")
.def("setVal", &Demo::setVal)
.def("setName", &Demo::setName)
;
main_module.attr("DemoObj") = spD1; // 添加智能指針到腳本,并重命名
call_method<void>(pModule , "SetObj"); // 在腳本中通過操縱智能指針來控制對象
std::cout << a.getName() << " " << a.getVal()<<endl;
}
catch (error_already_set)
{
PyErr_Print();
}
std::cout << "spD1->getName(): " << spD1->getName() <<std::endl;
std::cout << "spD1->getVal(): " << spD1->getVal() <<std::endl;
}
腳本內容:
def SetObj():
DemoObj.setVal(100);
DemoObj.setName('hello');
1.register_ptr_to_python <Demo_ptr>(); 沒有這句運行時會得到錯誤。關于register_ptr_to_python,boost中的解釋是:
“a function template which registers a conversion for smart pointers to Python”2.
dictionary["Demo"] = class_ <Demo>("Demo")
.def("setVal", &Demo::setVal)
.def("setName", &Demo::setName)
;
與方法一中的:
main_module.attr("Demo") = class_ <Demo>("Demo")
.def("setVal", &Demo::setVal)
.def("setName", &Demo::setName)
;
效果一樣。
-----------------------------------------------------------------------------------
以上就是關于如何將C++對象傳入python的一點習得,
如有任何錯誤,望不惜指正-----------------------------------------------------------------------------------
P.S.: cppblog提供的編輯器不好用
posted on 2011-06-01 17:34
zhaoyg 閱讀(3170)
評論(1) 編輯 收藏 引用 所屬分類:
C++和Python