我尝试再现一些here描述的例子,但是我在下面的代码中遇到了以下问题,它只是通过复制粘贴链接页面的相关部分来编写的。
#include <boost/python.hpp>
#include <boost/python/numpy.hpp>
#include <iostream>
using namespace std;
namespace p = boost::python;
namespace np = boost::python::numpy;
np::ndarray test()
{
int data[] = {1,2,3,4,5};
p::tuple shape = p::make_tuple(5);
p::tuple stride = p::make_tuple(sizeof(int));
p::object own;
np::dtype dt = np::dtype::get_builtin<int>();
np::ndarray array = np::from_data(data, dt, shape,stride,own);
std::cout << "Selective multidimensional array :: "<<std::endl
<< p::extract<char const *>(p::str(array)) << std::endl ;
return array;
}
BOOST_PYTHON_MODULE(test_module)
{
using namespace boost::python;
// Initialize numpy
Py_Initialize();
boost::python::numpy::initialize();
def("test", test);
}
当我编译为共享库并在python中加载模块时,
import test_module as test
print(test.test())
似乎ndarray
是由C ++代码正确创建的,但是python收到的版本是垃圾;打印的数组是:
[1 2 3 4 5]
[2121031184 32554 2130927769 32554 0]
可能是造成这种差异的原因是什么?
本周我遇到了同样的问题。为了解决我的问题,我使用动态内存:
np::ndarray test(){
int *data = malloc(sizeof(int) * 5);
for (int i=0; i < 5; ++i){
data[i] = i + 1;
}
p::tuple shape = p::make_tuple(5);
p::tuple stride = p::make_tuple(sizeof(int));
p::object own;
np::dtype dt = np::dtype::get_builtin<int>();
np::ndarray array = np::from_data(data, dt, shape, stride, own);
return array;
}
我认为根据这个答案的区别:https://stackoverflow.com/a/36322044/4637693是:
声明数组之间的区别
int array[n];
和
int* array = malloc(n * sizeof(int));
在第一个版本中,您声明一个具有自动存储持续时间的对象。这意味着只要存在调用它的函数,该数组就会存在。在第二个版本中,您将获得具有动态存储持续时间的内存,这意味着它将一直存在,直到它被显式释放为free。
我将在接下来的几周内花更多的时间来看看它是否适用于矩阵。
编辑
或者你可以使用boost like list中的动态结构:
np::ndarray test(){
boost::python::list my_list;
for (int i=0; i < 5; ++i){
my_list.append(i + 1);
}
np::ndarray array = np::from_object(my_list);
return array;
}
这项工作也适用于Matrix,例如:
np::ndarray test(){
//This will use a list of tuples
boost::python::list my_list;
for (int i=0; i < 5; ++i){
my_list.append(boost::python::make_tuple(i + 1, i, i-1));
}
//Just convert the list to a NumPy array.
np::ndarray array = np::from_object(my_list);
return array;
}
我假设(目前)通过使用boost函数,您将能够避免内存冲突。
在返回之前创建对数组的新引用解决了这个问题。好消息是np::ndarray
有一个copy()
方法可以实现完全相同的东西。因此,你应该添加
np::ndarray new_array = array.copy();
在返回声明之前