标签: boost-python

将`__str__`方法添加到Boost Python C++类时构建问题

我已经开始尝试使用boost python并遇到问题.我试图将一个C++类暴露给python,这没有任何问题.但我似乎无法实现__str__类的功能而不会出现我不明白的构建错误.

我正在使用boostpro的boost 1_42 prebuild.我使用cmake和vs2010编译器构建库.

我有一个非常简单的设置.头文件(tutorial.h)如下所示:

#include <iostream>
namespace TestBoostPython{
    class TestClass {
        private:
            double m_x;
        public:
            TestClass(double x);
            double Get_x() const;
            void Set_x(double x);
    };
    std::ostream &operator<<(std::ostream &ostr, const TestClass &ts);
};
Run Code Online (Sandbox Code Playgroud)

和相应的cpp文件看起来像:

#include <boost/python.hpp>
#include "tutorial.h"

using namespace TestBoostPython;

TestClass::TestClass(double x)
{
    m_x = x;
}

double TestClass::Get_x() const
{
    return m_x;
}
void TestClass::Set_x(double x)
{
    m_x = x;
}

std::ostream &operator<<(std::ostream &ostr, const TestClass &ts)
{
    ostr << ts.Get_x() << "\n";
    return ostr;
} …
Run Code Online (Sandbox Code Playgroud)

python boost-python

18
推荐指数
2
解决办法
2997
查看次数

从C++调用Python函数

我试图从C++实现调用Python函数.我认为它可以通过函数指针实现,但似乎不可能.我一直boost.python用来完成这个.

假设在Python中定义了一个函数:

def callback(arg1, arg2):
    #do something
    return something
Run Code Online (Sandbox Code Playgroud)

现在我需要将此函数传递给C++,以便可以从那里调用它.如何在C++端编写代码boost.python来实现这一目的?

c++ python callback boost-python

18
推荐指数
1
解决办法
1万
查看次数

boost_python导入错误:模块没有定义init函数

首先:我查看了相关问题,但遗憾的是它们并没有很大帮助.我正在尝试从外部库中包装枚举和类.

#include <Python.h>
#include <boost/python.hpp>
using namespace boost::python;

#include <libvpsc/rectangle.h>
using vpsc::Rectangle;
using vpsc::Dim;

BOOST_PYTHON_MODULE(adaptagrams)
{
    enum_<Dim>("dim")
        .value("x", vpsc::XDIM)
        .value("y", vpsc::YDIM)
        .value("unset", vpsc::UNSET)
    ;

    class_<Rectangle>("Rectangle",
        init<double, double, double, double, optional<bool> >())

        .add_property("centerX", &Rectangle::getCentreX)
        .add_property("centerY", &Rectangle::getCentreY)
        .add_property("width", &Rectangle::width, &Rectangle::set_width)
        .add_property("height", &Rectangle::height, &Rectangle::set_height)
    ;
}
Run Code Online (Sandbox Code Playgroud)

并编译:

g++ -fPIC -I/usr/include/python2.7 -c adaptagrams.cpp -o adaptagrams.o
g++ -shared -Wl,-soname,adaptagrams.so -o adaptagrams.so adaptagrams.o -lpython2.7  -lboost_python -lvpsc
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试导入.so模块时,出现错误:

ImportError: dynamic module does not define init function (PyInit_adaptagrams)
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

更新:当我重新启动Python并尝试导入时,我得到的第一个错误是:

ImportError: ./adaptagrams.so: undefined symbol: _ZN8topology13computeStressERKSt6vectorIPNS_4EdgeESaIS2_EE
Run Code Online (Sandbox Code Playgroud)

当我再次尝试时,第二个是从上面动态导入(2.7)和段错误(3.2).Boost是针对2.7和3.2进行编译的,我在每种方法上都链接正确的.

更新2: …

boost-python

18
推荐指数
2
解决办法
1万
查看次数

python/c ++ - 使用cmake编译共享库并使用distutils进行安装

我有一个boost.python项目,我使用cmake和make编译.它是python模块的一部分,我希望能够使用distutils安装该模块.我按照这里的说明创建了一个CMakeLists.txt文件,该文件首先编译共享库,然后设置setup.py,以便make install安装python模块.但是,虽然所有python文件都被distutils识别并移动到构建目录,但共享库却没有,我真的不知道为什么.

我的项目目录结构:

  • 项目
    • build(python distutils目录)
    • doc(模块文档)
    • 模块(主模块目录)
      • 核心(升级项目/库的目录)
        • CMakeLists.txt - 构建共享库
      • other_py_files(纯python文件的几个目录)
    • 的CMakeLists.txt
    • setup.py.in
    • setup.py(由cmake生成)

我的setup.py.in文件:

from distutils.core import setup
setup(
    name='module',
    version='${PACKAGE_VERSION}',
    packages=['module', 'module.core', 'module.other_py_files'],
    package_dir={'': '${CMAKE_CURRENT_SOURCE_DIR}'},
)
Run Code Online (Sandbox Code Playgroud)

我的CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)
project (module)

add_subdirectory(module/core)

find_program(PYTHON "python")

if (PYTHON)
  set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in")
  set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
  set(DEPS "${CMAKE_CURRENT_SOURCE_DIR}/pyQCD/__init__.py")
  set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/timestamp")

  configure_file(${SETUP_PY_IN} ${SETUP_PY})

  add_custom_command(OUTPUT ${OUTPUT}
    COMMAND ${PYTHON} ${SETUP_PY} build
    COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT}
    DEPENDS ${DEPS})

  add_custom_target(target ALL DEPENDS ${OUTPUT})

  install(CODE "execute_process(COMMAND ${PYTHON} ${SETUP_PY} install)")

endif()
Run Code Online (Sandbox Code Playgroud)

我认为distutils应该自动添加共享库扩展来构建目录,或者我在某处出错了?(共享库是一个基于C api(boost.python)构建的可导入的python模块,所以它应该可以工作吗?)

c++ python distutils cmake boost-python

18
推荐指数
1
解决办法
1万
查看次数

为std :: string找到Boost Python No to_python转换器

所以,我正在尝试创建一个to_python转换器,它允许我从一个公开的函数返回一个boost :: optional,并且如果设置了可选项,则将其视为T,否则视为None.基于我在C++ Sig上发现的帖子,我编写了以下代码.

template<typename T>
struct optional_ : private boost::noncopyable {
  struct conversion {
    static PyObject* convert(boost::optional<T> const& value) {
      if (value) {
        return boost::python::to_python_value<T>()(*value);
      }
      Py_INCREF(Py_None);
      return Py_None;
    }
  };
  explicit optional_() {
    boost::python::to_python_converter<boost::optional<T>, conversion>();
  }
};
Run Code Online (Sandbox Code Playgroud)

据我所知,它适用于转换选项,但是python会抛出以下异常"TypeError:No to_python(by-value)convert for C++ type:std :: string".我知道C++能够将字符串转换为python,因为我的大多数公开函数都返回字符串.为什么boost :: python :: to_python_value不能识别它,我怎样才能利用它拥有的任何转换器?

通过更改为以下内容(基于本文)修复:

template<typename T>
struct optional_ : private boost::noncopyable {
  struct conversion {
    static PyObject* convert(boost::optional<T> const& value) {
      using namespace boost::python;
      return incref((value ? object(*value) : …
Run Code Online (Sandbox Code Playgroud)

c++ boost-python

17
推荐指数
1
解决办法
2697
查看次数

使用boost :: python vector_indexing_suite包装std :: vector

我正在使用Python绑定(使用boost :: python)表示存储在文件中的数据的C++库.我的大多数半技术用户将使用Python与之交互,因此我需要尽可能将其设为Pythonic.但是,我也会让C++程序员使用API​​,所以我不想在C++方面妥协以适应Python绑定.

图书馆的很大一部分将由容器制成.为了让python用户看起来很直观,我希望它们的行为类似于python列表,即:

# an example compound class
class Foo:
    def __init__( self, _val ):
        self.val = _val

# add it to a list
foo = Foo(0.0)
vect = []
vect.append(foo)

# change the value of the *original* instance
foo.val = 666.0
# which also changes the instance inside the container
print vect[0].val # outputs 666.0
Run Code Online (Sandbox Code Playgroud)

测试设置

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/register_ptr_to_python.hpp>
#include <boost/shared_ptr.hpp>

struct Foo {
    double val;

    Foo(double a) : val(a) {}
    bool operator == (const …
Run Code Online (Sandbox Code Playgroud)

c++ python boost-python

17
推荐指数
1
解决办法
5788
查看次数

使用多个Python版本构建Boost

我使用Python的几个版本我的电脑上:2.6.6,2.7.62.7.9.当我用boost-python编译Boost时,我必须让Python在参数中使用.如果我想要兼容性,我是否要为每个Python版本编译Boost?(这是非常巨大的!)或者有没有办法只使用一个Boost版本和几个python版本?

python boost compilation boost-python

17
推荐指数
2
解决办法
1万
查看次数

Boost :: Python-可以自动从dict转换 - > std :: map?

我有一个C++类,其成员函数可以使用少量到大量的参数.让我们命名那些参数,af.所有参数都有默认值.作为我正在研究的python项目的一部分,我想将这个类暴露给python.目前,成员函数看起来像这样:

class myClass {
    public:
    // Constructors - set a-f to default values.

    void SetParameters(std::map<std::string, double> &);
    private:
    double a, b, c, d, e, f;
}

void myClass::SetParameters(std::map<std::string, double> const& params) {
    // Code to iterate over the map, and set any found key/value pairs to their
    // corresponding variable.  i.e.- "a" --> 2.0, would set myClass::a to 2.0
}
Run Code Online (Sandbox Code Playgroud)

理想情况下,在Python中,我想使用dict来实现这一点:

>>> A = myModule.myClass();
>>> A.SetParameters({'a': 2.2, 'd': 4.3, b: '9.3'})
Run Code Online (Sandbox Code Playgroud)

通过这种方式,用户可以按任何顺序输入值,并输入任意数量的值以进行覆盖.有关如何在boost :: python中实现这一点的任何想法?在我看来,我可以通过将地图输入更改为boost :: python对象,并使用提取函数来实现此目的.但是,这需要我更改我的库的接口(我更喜欢保留std :: map接口,并为python版本提供一些中间/自动转换技术).思考?

c++ python boost type-conversion boost-python

15
推荐指数
2
解决办法
1万
查看次数

类范围的枚举

我有一个带有枚举的c ++类,我想模仿它boost::python,以便我可以用MyClass.valuepython 编写.boost::python::class_没有enum_方法,我正在寻找解决方法.

  1. 我第一次尝试使用lambdas

    MyClass{
        enum{value1,value2};
    };
    
    class_<MyClass>("MyClass").add_property("value1",&[](){return value1;}).staticmethod("value1");
    
    Run Code Online (Sandbox Code Playgroud)

    这给出了编译器错误(in get_signaturefor add_property).我知道我可以为每个值创建getter方法,但这对我来说似乎很尴尬(打字方式).

  2. 使用attr:

    auto classObj=class_<MyClass>("MyClass");
    classObj.attr("value1")=(int)value1;
    classObj.attr("value2")=(int)value2;
    
    Run Code Online (Sandbox Code Playgroud)

    但它不能像.def其他方法一样链接返回对实例的引用.

有更优雅的解决方案吗?

c++ enums static-members boost-python

15
推荐指数
1
解决办法
3806
查看次数

在Boost Python中包装数组

我有一系列的C++结构,我试图用boost python包装.当这些结构包含数组时,我遇到了困难.我试图以最小的开销执行此操作,不幸的是我无法对结构本身进行任何修改.所以比如说我有

struct Foo
{
    int vals[3];
};
Run Code Online (Sandbox Code Playgroud)

我希望能够在python中访问它,如下所示:

f = Foo()
f.vals[0] = 10
print f.vals[0]
Run Code Online (Sandbox Code Playgroud)

现在我正在使用一系列get/set函数,但这些函数非常不优雅且与访问其他非数组成员不一致.这是我目前的解决方案:

int getVals (Foo f, int index) { return f.vals[index]; }
void setVals (Foo& f, int index, int value) { f.vals[index] = value; }

boost::python::class_< Foo > ( "Foo", init<>() )
    .def ( "getVals", &getVals )
    .def ( "setVals", &setVals );
Run Code Online (Sandbox Code Playgroud)

我可以使用get/set函数(因为在某些情况下我需要实现自定义get或set操作)但是我不确定如何合并[]运算符来访问数组的元素.在其他可以使用[]运算符访问的类中,我已经能够使用_ getitem __ setitem _这些已经完美地运行了,但是我不知道如果可能的话我会如何对类成员执行此操作.

c++ python boost boost-python

15
推荐指数
1
解决办法
7853
查看次数