我有一个用Python
编写的小C++
模块。此模块编译良好,可以导入Python
而不会出现任何错误。这些是代码的一些片段:
//...multiple includes
typedef variant<sqlite3 **, ... other types> VariantData; //!ONE
class ORM{
//... private fields
public:
VariantData Connect(int idx){
if(idx == 0) {
sqlite3 * conn;
sqlite3_open("reestr.db", &conn);
return &conn; //!TWO
// how to return a pointer to conn ???
// am I doing it right ???
}
}
//... other methods
// Python stuff
BOOST_PYTHON_MODULE(corm){
to_python_converter<VariantData, variant_to_object>(); //!THREE
implicitly_convertible<sqlite3 **, VariantData>(); //!THREE
//other unimportant code
因此,此代码编译时没有错误。但是,请注意由ONE
,TWO
和THREE
标记的四行代码,因为它们会导致错误。在我在第ONE
行的解释中,我定义了一个变量数据类型,它可以使用sqlite3 **
中的不同值。在第THREE
行,我定义Python
负责转换变量并在C++
和Python
之间传递的内容。但是,当我尝试在Python
中使用此模块时,我遇到了麻烦。我这样做:
>>> import corm
>>> c = corm.ORM(...initialization parameters...)
>>> r = c.Connect() # !ERROR
... No to_python (by-value) converter found for C++ type: sqlite *
我真的很想知道为什么Python
在这里讨论sqlite *
类型,而方法本身会return &conn;
,因此会返回sqlite3 **
类型的变量(我相信) 。所以,简而言之,我的问题是如何从Connect方法返回sqlite3 **
类型的指针。
答案 0 :(得分:0)
这是一个解决方案。我不确定它是否好,但至少它有效:
typedef variant<void *, ... other types> VariantData;
class ORM{
//... private fields
public:
VariantData Connect(int idx){
if(idx == 0) {
sqlite3 * conn;
sqlite3_open("reestr.db", &conn);
void * ref = ::operator new(sizeof(conn));
ref = conn;
return ref;
}
...
}
....
};
struct variant_to_object {
static PyObject* convert(VariantData const& v){
return boost::python::incref(
boost::python::object(v).ptr());
}
};
BOOST_PYTHON_MODULE(corm){
to_python_converter<VariantData, variant_to_object>();
implicitly_convertible<void *, VariantData>();
但是,当然,我应该关注ref
指针和delete
,当它不再使用时。