スポンサーリンク

Windows + VC++ + Python/C APIでPythonからCを呼び出す(2)プリミティブ型の引数をCへ渡す

Python側からintやfloatなどの型を渡す場合、全てPyObject*型として渡されるので、PyLong_AsLongなどの関数を使って実際の値に変換する必要がある。

なお、下記プログラムの「METH_O」は、「引数の数がselfを除き一つの時のみ」指定する。
それ以外はMETH_VARARGSを使用。

mymod.hpp

// mymod.hpp

#pragma once
#include <Python.h> // libファイルが必要 // anaconda3\Include にPython.hがある時、おそらく // anaconda3\libs にある。 #pragma comment (lib,"python39.lib")

      
// C++側の関数宣言
__declspec(dllexport) extern "C" PyObject * display_int(PyObject*, PyObject*);
__declspec(dllexport) extern "C" PyObject * display_bool(PyObject*, PyObject*);
__declspec(dllexport) extern "C" PyObject * display_float(PyObject*, PyObject*);
__declspec(dllexport) extern "C" PyObject * display_string(PyObject*, PyObject*);
      
      
// 関数へアクセスする方法一覧
static PyMethodDef method_list[] = {
    // Pythonで使用する関数名 , C++内で使用する関数名 , 引数の個数に関するフラグ , docstring
    { "disp_int", (PyCFunction)display_int, METH_O , nullptr },
    { "disp_bool", (PyCFunction)display_bool, METH_O , nullptr },
    { "disp_float", (PyCFunction)display_float, METH_O , nullptr },
    { "disp_string", (PyCFunction)display_string, METH_O , nullptr },

    // 配列の最後は全てNULLの要素を入れておく
    { nullptr, nullptr, 0, nullptr }
};
// モジュールを定義する構造体
static PyModuleDef module_def = {
    PyModuleDef_HEAD_INIT,
    "DLLforPython",               // モジュール名
    "Example of pyhton wrapper",  // モジュール説明
    0,
    method_list                   // Structure that defines the methods of the module
};

PyMODINIT_FUNC PyInit_DLLforPython() {
    return PyModule_Create(&module_def);
}

mymod.cpp

// mymod.cpp

#include "mymod.hpp"

// intを受け取る
PyObject* display_int(PyObject*, PyObject* val) {

  long value = PyLong_AsLong(val);
  printf("%d\n", value);

  return Py_None;
}
      
// boolを受け取る
PyObject* display_bool(PyObject*, PyObject* val) {

  int value = PyObject_IsTrue(val);

  puts(bool(value) ? "TRUE" : "FALSE");

  return Py_None;
}
      
// floatを受け取る
PyObject * display_float(PyObject*, PyObject* val) {

  double value = PyFloat_AsDouble(val);
  printf("%lf\n", value);

  return Py_None;
}
      
// stringを受け取る
PyObject * display_string(PyObject*, PyObject* val) {

  const char* value = PyUnicode_AsUTF8(val);
  printf("%s\n", value);

  return Py_None;

}

test.py

import DLLforPython

DLLforPython.disp_int(500)

DLLforPython.disp_bool(True)

DLLforPython.disp_float(1.5)

DLLforPython.disp_string('test')
500
TRUE
1.500000
test

コメントを残す

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

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


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