随笔-59  评论-36  文章-0  trackbacks-0
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 阅读(3073) 评论(1)  编辑 收藏 引用 所属分类: C++和Python

评论:
# re: 通过Boost::Python实现C++对象导入python环境 2012-10-05 21:03 | Frey
小错误
std::cout << a.getName() << " " << a.getVal()<<endl;

endl;应为std::endl;
  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理