我是python的新手,我看过boost python,它看起来非常令人印象深刻.然而,通过介绍我找不到任何示例,对象的向量作为python列表/元组返回.
即举个例子,我想公开类X,Cont及其所有函数.关键位返回X的向量或字符串到python
class X {};
class Cont {
.....
// how can this be exposed using boost python
const std::vector<X>& const_ref_x_vec() const { return x_vec_;}
std::vector<X> value_x_vec() const { return x_vec;}
const std::vector<std::string>& const_ref_str_vec() const { return str_vec_;}
std::vector<std::string> value_str_vec() const { return str_vec_; }
...
private:
std::vector<X> x_vec_;
std::vector<std::string> str_vec_;
};
Run Code Online (Sandbox Code Playgroud)
我尝试公开const_ref_x_vec(),value_x_vec()等函数的无效尝试只会导致编译错误.
从谷歌搜索我没有看到任何支持按值或引用返回向量的示例.使用boost python甚至可以实现这一点吗?有没有解决方法?我应该在这种情况下使用SWIG吗?
任何帮助赞赏.
Avtar
我有这个代码 snnipet (整个程序正确编译和链接):
...
try
{
boost::python::exec_file(
"myscript.py", // this file contains a syntax error
my_main_namespace,
my_local_namespace
);
return true;
}
catch(const boost::python::error_already_set &)
{
PyObject *ptype, *pvalue, *ptraceback;
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
// the next line crashes on syntax error
std::string error = boost::python::extract<std::string>(pvalue);
...
}
Run Code Online (Sandbox Code Playgroud)
程序尝试执行的文件存在语法错误,因此引发异常。当程序尝试获取错误消息时崩溃...
该代码可以很好地处理运行时错误,但会因语法错误而崩溃。
我如何获取此类错误的错误字符串?
提前致谢
我在使用boost.python暴露的现有C++库中集成boost.signals2时遇到问题.
我有一个暴露于python的类std::shared_ptr.这个类应该能够在某些事件上提出一些信号.因此我暴露了connect_slot一个boost::python::object以参数为参数的函数.如果我在连接一个插槽后直接发出一个信号,一切正常,但是如果该类后来提升信号,我会收到分段错误.
我认为这可能与c ++ lib中的线程有关(它也使用了boost :: asio等)
以下是一些代码段:
MyClass.h:
public:
typedef boost::signals2::signal<void (std::shared_ptr<int>)> signal_my_sig;
void connect_slot(boost::python::object const & slot);
private:
signal_my_sig m_sig;
Run Code Online (Sandbox Code Playgroud)
MyClass.cpp:
void MyClass::connect_slot(boost::python::object const & slot) {
std::cout << "register shd" << std::endl;
m_sig.connect(slot);
m_sig(12345); // this works
}
void MyClass::some_later_event() {
m_sig(654321); // this does not work
}
Run Code Online (Sandbox Code Playgroud)
我在python中用自定义python函数调用MyClass :: connect_slot函数,如下所示:
def testfunc(some_int):
print("slot called")
m = myext.MyClass()
m.connect_slot(testfunc)
Run Code Online (Sandbox Code Playgroud)
引发的分段错误的回溯(使用gdb)MyClass::some_later_event如下所示:
[Thread debugging using libthread_db enabled]
Using host libthread_db library …Run Code Online (Sandbox Code Playgroud) 我有一个用于Python列表的c ++ boost python对象(PyObject上的boost包装器),
PyObject * pyList = func(...);
boost::python::object listObj(handle<>(boost::python::borrowed(pyList)));
Run Code Online (Sandbox Code Playgroud)
我可以通过对其执行以下操作来验证这确实是一个列表
boost::python::object np = import("numpy");
boost::python::np_difference = np.attr("diff");
np_difference(listObj);
for(int i=0; i<len(listObj); i++){
double value = boost::python::extract<double>(listObj[i]);
cout << i << " " << value << endl;
}
Run Code Online (Sandbox Code Playgroud)
它从i-1元素中减去第ith个元素并创建一个新列表,然后提取每个列表并将其打印到C ++中的stdout中。
我想做的是将此listObj与我定义为的打印功能一起使用
boost::python::object print = std.attr("print");
Run Code Online (Sandbox Code Playgroud)
但是我只想打印我指定的元素之一。在python中,我只会写
print myList[0]
Run Code Online (Sandbox Code Playgroud)
因为它只是一个python列表。但是当我尝试
print(listObj[0]);
Run Code Online (Sandbox Code Playgroud)
在C ++中使用Boost python我得到
Error in Python: <type 'exceptions.TypeError'>: No to_python (by-value) converter found for C++ type: boost::python::api::proxy<boost::python::api::item_policies>.
Run Code Online (Sandbox Code Playgroud)
那么,如何从c ++内部访问来自python列表对象的单个元素,并在python调用中使用它,例如上述的print方法(或其他需要输入字符串的python函数)呢?
bp :: extract将bp :: object转换为特定类型.问题是怎么做副歌?
我们假设我有一个PointContainer和Point类.我需要一个具有这种签名的功能
bp::object get_point(const PointContainer &, const bp::object & input);
Run Code Online (Sandbox Code Playgroud)
它应检查输入参数是否为整数.在这种情况下,它返回PointContainer中具有相应索引的Point实例的引用.如果它不是整数,那么函数检查输入是否是切片对象(例如mylist [1:10:2]).在这种情况下,它返回PointContainer的副本.
问题是如何将Point,PointContainer实例转换为bp :: objects?
有关上述课程的一些细节
class_<Point<int>>("Point")
.def("__getitem__", get_point_item)
.def("__setitem__", set_point_item)
.def("__len__", get_point_size)
.def("__str__", print_point)
.def("__eq__", &Point<int>::operator ==)
.def("__ne__", &Point<int>::operator !=)
.def("set_x", &Point<int>::set_x)
.def("get_x", &Point<int>::get_x)
.def("set_y", &Point<int>::set_y)
.def("get_y", &Point<int>::get_y)
;
typedef std::vector<Point<int>> PointContainer;
typedef boost::shared_ptr<PointContainer> PointContainerPtr;
class_<PointContainer, PointContainerPtr>("PointContainer")
.def("__iter__", iterator<PointContainer>())
.def("__getitem__", get_point)
.def("__setitem__", set_point)
.def("__len__", &PointContainer::size)
.def("append", push_point)
.def("reserve", &PointContainer::reserve)
.def("clear", &PointContainer::clear)
;
Run Code Online (Sandbox Code Playgroud) 我有一个包含std :: function属性的类.我使用成员函数设置此属性的值,因此该类看起来像这样:
class ClassName
{
public:
void SetCallbackFunction(std::function<void (int i)> callbackFun) {
m_callbackFunction = callbackFun;
}
protected:
std::function<void (int i)> m_callbackFunction;
};
Run Code Online (Sandbox Code Playgroud)
我需要将这个类暴露给Python,当然,我需要公开该SetCallbackFunction函数.我怎么能用boost :: python做到这一点?
我想将一个TestObj实例从C++代码传递给python.这里发布的代码在cout中产生错误:"为C++类型找不到to_python(by-value)转换器:class TestObj".如果我将对象创建移动main_module.attr("obj") = obj;到BOOST_PYTHON_MODULE宏中,代码运行正常.
当我尝试*TestObj使用或不使用boost :: ptr 时,会发生类似的事情.
testembed.py:
import sfgame
print("old x: " + str(obj.x))
obj.x = 10
print("new x: " + str(obj.x))
Run Code Online (Sandbox Code Playgroud)
testobj.h
class TestObj{
public:
TestObj();
int x;
int getX();
void setX(int xv);
};
Run Code Online (Sandbox Code Playgroud)
testobj.cpp
#include "TestObj.h"
TestObj::TestObj(){
}
int TestObj::getX(){
return x;
}
void TestObj::setX(int xv){
x = xv;
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include <boost/python.hpp>
#include "TestObj.h"
using namespace boost::python;
BOOST_PYTHON_MODULE(sfgame){
class_<TestObj>("TestObj")
.add_property("x", &TestObj::getX, &TestObj::setX)
;
}
int main(){
Py_Initialize();
object main_module = import("__main__"); …Run Code Online (Sandbox Code Playgroud) 我正在尝试包装一个使用 Boost.Python 处理二进制值的 C++ 类。对于此类,“<<”运算符已定义为
std::ostream &operator<<(std::ostream &output, const bin &inbin);
Run Code Online (Sandbox Code Playgroud)
我试着用
class_<bin>("bin", init<>())
.def(str(self));
Run Code Online (Sandbox Code Playgroud)
但是,编译会引发此错误:
boost/python/def_visitor.hpp:31:9: error: no matching function for call to
‘boost::python::api::object::visit(boost::python::class_<itpp::bin>&) const’
Run Code Online (Sandbox Code Playgroud)
我不知道如何解决这个错误,有人知道吗?
参考:http : //www.boost.org/doc/libs/1_31_0/libs/python/doc/tutorial/doc/class_operators_special_functions.html
我正在尝试使用 MSVC2015 和 Python 3.7 生成 Boost.Python 1.65.1 库。
我有这个编译错误:
libs\python\src\converter\builtin_converters.cpp(51): error C2440: 'return': cannot convert from 'const char *' to 'void *'
libs\python\src\converter\builtin_converters.cpp(51): note: Conversion loses qualifiers
Run Code Online (Sandbox Code Playgroud)
相关代码(返回错误):
void* convert_to_cstring(PyObject* obj)
{
return PyUnicode_Check(obj) ? _PyUnicode_AsString(obj) : 0;
}
Run Code Online (Sandbox Code Playgroud)
对我来说,这似乎是一个真正的错误。b2 配置中是否有选项可以使编译器在此方面更加灵活?
我用这个作为信息:
https://codeyarns.com/2014/06/06/how-to-build-boost-using-visual-studio/
如何在 Visual Studio 2010 中使用 Boost
编辑:boost 1.69.0 没有这个错误,但我必须使用 1.65.1
Edit2:他们在 1.69.0 中更改了此代码:
PyUnicode_Check(obj) ? const_cast<void*>(reinterpret_cast<const void*>(_PyUnicode_AsString(obj))) : 0;
Run Code Online (Sandbox Code Playgroud) 我使用模板化的游标来为几个类定义统一的接口.为了定义__str__和__repr__方法,我想以编程方式"X"从boost::python::class对象中获取类名(在引用文档中).那可能吗?
通过将类名作为参数传递给访问者的构造函数,可以很容易地处理它,但自动拥有它会更优雅.
我的目标是使用boost python创建一个python扩展模块.问题是,当共享库中的代码使用dlopen访问同一个库中的符号时,它会失败(详情如下).看起来模块中的符号没有加载到python进程的符号表中
我在共享库myTest.so中有以下代码
// File 1
extern "C" void target_func() {
std::cout << "Works!" << std::endl;
}
// File 2
typedef void (*Func) ();
void run() {
void *handle = dlopen(0, RTLD_NOW | RTLD_GLOBAL)
Func *method = (Func *)dlsym(handle, "target_func");
// check if method is NULL and fail
}
Run Code Online (Sandbox Code Playgroud)
它包含在一个boost python模块中,如图所示 -
BOOST_PYTHON_MODULE(myTest) {
def("run", run);
}
Run Code Online (Sandbox Code Playgroud)
导入python模块并执行时,上面的代码失败
import myTest
myTest.run()
undefined symbol: target_func
Run Code Online (Sandbox Code Playgroud)
但是当我将myTest.so与调用run的main函数链接时,没有问题
int main(int argc, char **argv) {
run();
}
Output: Works!
Run Code Online (Sandbox Code Playgroud) 我有以下代码
#include <boost/python.hpp>
int main()
{
Py_Initialize();
namespace python = boost::python;
try {
python::object main = python::import("sample");
} catch(...) {
PyErr_Print();
PyErr_Clear();
}
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
ImportError: No module named sample
Run Code Online (Sandbox Code Playgroud)
我将我的 sample.py 放在与该程序相同的目录中。
假设C++中有一个类MyArray。它实现了一个数组SomeType为了__getitem__在Python中为其创建一个函数,我做了这样的事情
const SomeType& getitem(const MyArray *arr, PyObject *slice) {
// ???
}
BOOST_PYTHON_MODULE(mymodule)
{
class_<MyArray>("MyArray")
.def("__getitem__", &getitem)
// probably some other methods...
;
}
Run Code Online (Sandbox Code Playgroud)
slice使用这些函数可以获取索引。然而,“ Boost::Python 的设计理念是用户永远不会接触 PyObject* ”。
有没有更好的“提升方式”来做到这一点?
boost-python ×13
c++ ×9
python ×8
boost ×6
c++11 ×2
dlopen ×1
exception ×1
ostream ×1
python-2.7 ×1
python-3.x ×1
slice ×1
visitor ×1