将 boost::python::numpy::ndarray 作为(默认或非默认)参数传递给 boost::python 函数?
Passing boost::python::numpy::ndarray as (default or not) argument of a boost::python function?
是否可以将 boost::python::numpy::ndarray 作为(默认或非默认)参数传递给 boost::python 函数?
dummy 没有 ndarray。像一个 ndarray 参数一样愚蠢,但没有默认值。 silly 有一个 ndarray 作为默认值。
>> more dummy.cpp stupid.cpp silly.cpp
::::::::::::::
dummy.cpp
::::::::::::::
#include <boost/python.hpp>
namespace bp = boost::python;
int f(double x, double y=1.0) {return (int)(x+y);};
BOOST_PYTHON_MODULE(dummy)
{
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=1.0 ) );
}
::::::::::::::
stupid.cpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, double y=1.0) {return (int)(x.shape(0)+y);};
BOOST_PYTHON_MODULE(stupid)
{
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=1.0 ) );
}
::::::::::::::
silly.cpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, np::ndarray * y=nullptr) {return (int)(y ? x.shape(0)+y->shape(0) : x.shape(0));};
BOOST_PYTHON_MODULE(silly)
{
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=nullptr ) );
}
>> make
g++ -I /usr/include/python2.7 -o dummy.so -fPIC -shared dummy.cpp -lboost_python -lboost_numpy -lpython2.7
g++ -I /usr/include/python2.7 -o stupid.so -fPIC -shared stupid.cpp -lboost_python -lboost_numpy -lpython2.7
g++ -I /usr/include/python2.7 -o silly.so -fPIC -shared silly.cpp -lboost_python -lboost_numpy -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dummy; dummy.f(1)
2
>>> import numpy; import stupid; stupid.f(numpy.array([1, 2, 3]))
Segmentation fault
更新
试图在 f
中添加 Py_Initialize(); np::initialize();
但没有成功
>> more stupid.cpp silly.cpp
::::::::::::::
stupid.cpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, double y=1.0) {
Py_Initialize();
np::initialize();
return (int)(x.shape(0)+y);
};
BOOST_PYTHON_MODULE(stupid)
{
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=1.0 ) );
}
::::::::::::::
silly.cpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, np::ndarray * y=nullptr) {
Py_Initialize();
np::initialize();
return (int)(y ? x.shape(0)+y->shape(0) : x.shape(0));
};
BOOST_PYTHON_MODULE(silly)
{
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=nullptr ) );
}
>> make
g++ -I /usr/include/python2.7 -o stupid.so -fPIC -shared stupid.cpp -lboost_python -lboost_numpy -lpython2.7
g++ -I /usr/include/python2.7 -o silly.so -fPIC -shared silly.cpp -lboost_python -lboost_numpy -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy; import stupid; stupid.f(numpy.array([1, 2, 3]))
Segmentation fault
更新
好的,让它与调用 in BOOST_PYTHON_MODULE
一起工作。仍然使用默认参数(silly
示例)。
>> more stupid.cpp silly.cpp
::::::::::::::
stupid.cpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, double y=1.0) {
return (int)(x.shape(0)+y);
};
BOOST_PYTHON_MODULE(stupid)
{
Py_Initialize();
np::initialize();
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=1.0 ) );
}
::::::::::::::
silly.cpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, np::ndarray * y=nullptr) {
return (int)(y ? x.shape(0)+y->shape(0) : x.shape(0));
};
BOOST_PYTHON_MODULE(silly)
{
Py_Initialize();
np::initialize();
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=nullptr ) );
}
>> make
g++ -I /usr/include/python2.7 -o stupid.so -fPIC -shared stupid.cpp -lboost_python -lboost_numpy -lpython2.7
g++ -I /usr/include/python2.7 -o silly.so -fPIC -shared silly.cpp -lboost_python -lboost_numpy -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy; import stupid; stupid.f(numpy.array([1, 2, 3]))
4
>>> import numpy; import silly; silly.f(numpy.array([1, 2, 3]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: No to_python (by-value) converter found for C++ type: decltype(nullptr)
解决方法
>> more silly.cpp
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, bp::object y) {
np::ndarray yy = np::array(bp::list());
if (!y.is_none()) yy = bp::extract<np::ndarray>(y);
return (int)(x.shape(0)+yy.shape(0));
};
BOOST_PYTHON_MODULE(silly)
{
Py_Initialize();
np::initialize();
bp::def("f", f, ( bp::arg("x"), bp::arg("y") ) );
}
>> make
g++ -I /usr/include/python2.7 -o silly.so -fPIC -shared silly.cpp -lboost_python -lboost_numpy -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy; import silly; silly.f(numpy.array([1, 2, 3]), numpy.array([1, 2]))
5
>>> import numpy; import silly; silly.f(numpy.array([1, 2, 3]), None)
3
为了能够使用 numpy
首先初始化 Python
运行时和 numpy
模块:
Py_Initialize();
np::initialize();
未能调用这些结果导致分段错误。
============================================= ==========================
对于 silly.cpp
不需要解决方法。这是实现:
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, np::ndarray y = np::array(bp::list()) ) {
return (int)(x.shape(0)+y.shape(0));
};
BOOST_PYTHON_MODULE(silly)
{
Py_Initialize();
np::initialize();
bp::def("f", f, ( bp::arg("x"), bp::arg("y") = np::array(bp::list()) ) );
}
而测试结果:
>>> import numpy, silly; silly.f(numpy.array([1, 2, 3]), numpy.array([1, 2]))
5
>>> import numpy, silly; silly.f(numpy.array([1, 2, 3]))
3
是否可以将 boost::python::numpy::ndarray 作为(默认或非默认)参数传递给 boost::python 函数?
dummy 没有 ndarray。像一个 ndarray 参数一样愚蠢,但没有默认值。 silly 有一个 ndarray 作为默认值。
>> more dummy.cpp stupid.cpp silly.cpp
::::::::::::::
dummy.cpp
::::::::::::::
#include <boost/python.hpp>
namespace bp = boost::python;
int f(double x, double y=1.0) {return (int)(x+y);};
BOOST_PYTHON_MODULE(dummy)
{
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=1.0 ) );
}
::::::::::::::
stupid.cpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, double y=1.0) {return (int)(x.shape(0)+y);};
BOOST_PYTHON_MODULE(stupid)
{
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=1.0 ) );
}
::::::::::::::
silly.cpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, np::ndarray * y=nullptr) {return (int)(y ? x.shape(0)+y->shape(0) : x.shape(0));};
BOOST_PYTHON_MODULE(silly)
{
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=nullptr ) );
}
>> make
g++ -I /usr/include/python2.7 -o dummy.so -fPIC -shared dummy.cpp -lboost_python -lboost_numpy -lpython2.7
g++ -I /usr/include/python2.7 -o stupid.so -fPIC -shared stupid.cpp -lboost_python -lboost_numpy -lpython2.7
g++ -I /usr/include/python2.7 -o silly.so -fPIC -shared silly.cpp -lboost_python -lboost_numpy -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dummy; dummy.f(1)
2
>>> import numpy; import stupid; stupid.f(numpy.array([1, 2, 3]))
Segmentation fault
更新
试图在 f
中添加 Py_Initialize(); np::initialize();
但没有成功
>> more stupid.cpp silly.cpp
::::::::::::::
stupid.cpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, double y=1.0) {
Py_Initialize();
np::initialize();
return (int)(x.shape(0)+y);
};
BOOST_PYTHON_MODULE(stupid)
{
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=1.0 ) );
}
::::::::::::::
silly.cpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, np::ndarray * y=nullptr) {
Py_Initialize();
np::initialize();
return (int)(y ? x.shape(0)+y->shape(0) : x.shape(0));
};
BOOST_PYTHON_MODULE(silly)
{
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=nullptr ) );
}
>> make
g++ -I /usr/include/python2.7 -o stupid.so -fPIC -shared stupid.cpp -lboost_python -lboost_numpy -lpython2.7
g++ -I /usr/include/python2.7 -o silly.so -fPIC -shared silly.cpp -lboost_python -lboost_numpy -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy; import stupid; stupid.f(numpy.array([1, 2, 3]))
Segmentation fault
更新
好的,让它与调用 in BOOST_PYTHON_MODULE
一起工作。仍然使用默认参数(silly
示例)。
>> more stupid.cpp silly.cpp
::::::::::::::
stupid.cpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, double y=1.0) {
return (int)(x.shape(0)+y);
};
BOOST_PYTHON_MODULE(stupid)
{
Py_Initialize();
np::initialize();
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=1.0 ) );
}
::::::::::::::
silly.cpp
::::::::::::::
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, np::ndarray * y=nullptr) {
return (int)(y ? x.shape(0)+y->shape(0) : x.shape(0));
};
BOOST_PYTHON_MODULE(silly)
{
Py_Initialize();
np::initialize();
bp::def("f", f, ( bp::arg("x"), bp::arg("y")=nullptr ) );
}
>> make
g++ -I /usr/include/python2.7 -o stupid.so -fPIC -shared stupid.cpp -lboost_python -lboost_numpy -lpython2.7
g++ -I /usr/include/python2.7 -o silly.so -fPIC -shared silly.cpp -lboost_python -lboost_numpy -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy; import stupid; stupid.f(numpy.array([1, 2, 3]))
4
>>> import numpy; import silly; silly.f(numpy.array([1, 2, 3]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: No to_python (by-value) converter found for C++ type: decltype(nullptr)
解决方法
>> more silly.cpp
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, bp::object y) {
np::ndarray yy = np::array(bp::list());
if (!y.is_none()) yy = bp::extract<np::ndarray>(y);
return (int)(x.shape(0)+yy.shape(0));
};
BOOST_PYTHON_MODULE(silly)
{
Py_Initialize();
np::initialize();
bp::def("f", f, ( bp::arg("x"), bp::arg("y") ) );
}
>> make
g++ -I /usr/include/python2.7 -o silly.so -fPIC -shared silly.cpp -lboost_python -lboost_numpy -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy; import silly; silly.f(numpy.array([1, 2, 3]), numpy.array([1, 2]))
5
>>> import numpy; import silly; silly.f(numpy.array([1, 2, 3]), None)
3
为了能够使用 numpy
首先初始化 Python
运行时和 numpy
模块:
Py_Initialize();
np::initialize();
未能调用这些结果导致分段错误。
============================================= ==========================
对于 silly.cpp
不需要解决方法。这是实现:
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
namespace bp = boost::python;
namespace np = boost::python::numpy;
int f(np::ndarray x, np::ndarray y = np::array(bp::list()) ) {
return (int)(x.shape(0)+y.shape(0));
};
BOOST_PYTHON_MODULE(silly)
{
Py_Initialize();
np::initialize();
bp::def("f", f, ( bp::arg("x"), bp::arg("y") = np::array(bp::list()) ) );
}
而测试结果:
>>> import numpy, silly; silly.f(numpy.array([1, 2, 3]), numpy.array([1, 2]))
5
>>> import numpy, silly; silly.f(numpy.array([1, 2, 3]))
3