生のポインタを使ってデータにアクセスする方法
ndarray ラッパの利点の 1 つは、同じデータを Python と C++ の両方で使え、変更が両方に反映されることである。from_data
メソッドがこれを可能にする。
これまで同様、まず必要なヘッダファイルのインクルードと名前空間の準備を行い、Python ランタイムと numpy モジュールを初期化する。
#include <boost/python/numpy.hpp>
#include <iostream>
namespace p = boost::python;
namespace np = boost::python::numpy;
int main(int argc, char **argv)
{
Py_Initialize();
np::initialize();
C++ で配列を作成し、そのポインタを from_data
メソッドに渡して ndarray を作成する。
int arr[] = {1,2,3,4,5};
np::ndarray py_array = np::from_data(arr, np::dtype::get_builtin<int>(),
p::make_tuple(5),
p::make_tuple(sizeof(int)),
p::object());
元の C++ 配列と ndarray を印字し、同じであるかチェックする。
std::cout << "C++ array :" << std::endl;
for (int j=0;j<4;j++)
{
std::cout << arr[j] << ' ';
}
std::cout << std::endl
<< "Python の ndarray :" << p::extract<char const *>(p::str(py_array)) << std::endl;
ここで Python の ndarray で要素 1 つを変更し、元の C++ 配列で値が変更されたかチェックする。
py_array[1] = 5 ;
std::cout << "ndarray の作成に使用した C++ 配列に変更が反映されたか?" << std::endl;
for (int j = 0; j < 5; j++)
{
std::cout << arr[j] << ' ';
}
次に元の C++ 配列で要素 1 つを変更し、Python の ndarray に反映されたか見る。
arr[2] = 8;
std::cout << std::endl
<< "Python の ndarray に変更が反映されたか?" << std::endl
<< p::extract<char const *>(p::str(py_array)) << std::endl;
}
以上のように、変更はフロントエンド間で反映される。from_data
メソッドが C++ 配列を参照で渡して ndarray を作成し、データを格納するのに同じ場所を使っているため、このような結果になる。