簡體   English   中英

Boost :: python使用和返回模板公開C ++函數

[英]Boost::python Exposing C++ functions using and returning templates

我需要為C ++代碼庫構建python綁定。 我使用boost :: python並且在嘗試使用和返回模板公開包含函數的類時遇到了問題。 這是一個典型的例子

class Foo 
{ 
    public: 
        Foo(); 
        template<typename T> Foo& setValue(
            const string& propertyName, const T& value); 
        template<typename T> const T& getValue(
            const string& propertyName); 
}; 

典型的T是字符串,雙,矢量。

閱讀完文檔后 ,我嘗試使用所有類型的薄包裝器。 這是string和double的包裝器以及相應的類聲明。

Foo & (Foo::*setValueDouble)(const std::string&,const double &) = 
    &Foo::setValue; 
const double & (Foo::*getValueDouble)(const std::string&) = 
    &Foo::getValue;

Foo & (Foo::*setValueString)(const std::string&,const std::string &) = 
    &Foo::setValue; 
const std::string & (Foo::*getValueString)(const std::string&) = 
    &Foo::getValue;

class_<Foo>("Foo") 
    .def("setValue",setValueDouble, 
        return_value_policy<reference_existing_object>()) 
    .def("getValue",getValueDouble,
        return_value_policy<copy_const_reference>()) 
    .def("getValue",getValueString, 
        return_value_policy<copy_const_reference>()) 
    .def("setValue",setValueString, 
        return_value_policy<reference_existing_object>());

它編譯好,但是當我嘗試使用python綁定時,我得到了一個C ++異常。

>>> f = Foo()  
>>> f.setValue("key",1.0) 
>>> f.getValue("key") 
Traceback (most recent call last): 
  File "<stdin>", line 1, in ? 
  RuntimeError: unidentifiable C++ exception

有趣的是,當我只將Foo暴露給雙倍或字符串值時,即

class_<Foo>("Foo") 
    .def("getValue",getValueString, 
        return_value_policy<copy_const_reference>()) 
    .def("setValue",setValueString, 
        return_value_policy<reference_existing_object>());

它工作正常。 我錯過了什么嗎?

這可能與您的問題沒有直接關系,但我不相信使用這樣的模板進行函數簽名轉換。 我會像這樣包裹它:

class_<Foo>("Foo") 
    .def("setValue", &Foo::setValue<double>, 
        return_value_policy<reference_existing_object>()) 
    .def("getValue", &Foo::getValue<double>,
        return_value_policy<copy_const_reference>()) 
    .def("getValue", &Foo::getValue<std::string>, 
        return_value_policy<copy_const_reference>()) 
    .def("setValue", &Foo::setValue<std::string>, 
        return_value_policy<reference_existing_object>());

如果這不起作用,您可能需要創建一些填充函數:

Foo& setValueDouble(foo& self, const string& propertyName, const double value)
{ 
    return self.setValue(propertyName, value)
}
...

並將那些人視為他們的成員職能。

在Boost :: Python中導出多個函數重載到同一個名稱是完全有效的事情,所以我認為這不是問題所在。

我懷疑問題是boost :: python不知道調用“getValue”的重載 - 應該調用getValueDouble還是getValueString? 如果你明確地將它們綁定為getValueString和getValueDouble(作為方法名稱),我敢打賭它會起作用。

如何為返回/獲取boost :: python :: object的getter / setter創建C ++包裝器? 然后,您可以簡單地確定您在C ++包裝器中獲得的類型,並將其打包/解壓縮到boost :: python :: object中。

struct FooWrap : public Foo
{
    using boost::python;
    Foo& setValueO(const string& propertyName, const object& obj)
    {
        object value;
        if(PyInt_Check(obj.ptr())) {
            return setValue<int>(propertyName, extract<int>(obj);
        } else if(PyFloat_Check(obj.ptr())) {
            return setValue<double>(propertyName, extract<double>(obj);
        } else if(PyString_Check(obj.ptr())) {
            return setValue<std::string>(propertyName, extract<std::string>(obj);
        }
        // etc...
    }

    object getValueO(const std::string& propertyName)
    {
        if(determineType() == TYPE_INT) { // however you determine the type
            return object(getValue<int>(propertyName));
        } else if(determineType() == TYPE_DOUBLE)   {
            return object(getValue<double>(propertyName));
        } else if(determineType() == TYPE_STRING)   {
            return object(getValue<std::string>(propertyName));
        }
        // etc...
    }
};

class_<Foo>("Foo") 
    .def("setValue", &FooWrap::setValueO, 
        return_value_policy<reference_existing_object>()) 
    .def("getValue", &FooWrap::getValueO,
        return_value_policy<copy_const_reference>()) 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM