スポンサーリンク

Windows + VC++ + Python/C APIでPythonからCを呼び出す(5)CのポインタをPythonへ渡す

ポインタを渡す場合はPyCapsule_Newで包んで渡す。

データがnewされたものなら、一緒にdeleterも渡すことができる。

mymod.hpp 変更

// C++側の関数宣言

// 配列作成
__declspec(dllexport) extern "C" PyObject * create_array_in_c(PyObject*);

// 配列からアイテム取得
__declspec(dllexport) extern "C" PyObject * get_item_in_c(PyObject*, PyObject* args);


// 関数へアクセスする方法一覧
static PyMethodDef method_list[] = {
    { "create_array", (PyCFunction)create_array_in_c, METH_VARARGS , nullptr },
    { "get_item", (PyCFunction)get_item_in_c, METH_VARARGS , nullptr },

    // 配列の最後は全てNULLの要素を入れておく
    { nullptr, nullptr, 0, nullptr }
};

mymod.cpp

// mymod.cpp

#include "mymod.hpp"

#define NAME nullptr

// デリータ
void array_deleter(PyObject* obj)
{
  long* p = (long*)PyCapsule_GetPointer(obj, NAME);
  delete [] p;
}

// データを作成する関数
PyObject* create_array_in_c(PyObject*) {

  long* p = new long[5]{
    0,1,2,3,4
  };

  // ポインタをPyObjectへ変換
  // 同時にデリータを指定して自動解放を可能にする
  PyObject* pyo = PyCapsule_New(p, NAME, array_deleter);

  return pyo;
}

PyObject * get_item_in_c(PyObject*, PyObject * args) {

  PyObject* dataptr;
  int index;

  // argsから引数取り出し
  // PyObject* は 'O' を使用
  if (!PyArg_ParseTuple(args, "Oi", &dataptr, &index)) return NULL;

  long* p = (long*)PyCapsule_GetPointer(dataptr, NAME);

  return PyLong_FromLong(p[index]);

}

test.py

import DLLforPython

array = DLLforPython.create_array()

print( DLLforPython.get_item(array,3) )
3

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: