サーチ…


Cエクステンションを持つHello World

以下のCソースファイル(デモンストレーションの目的でhello.cと呼ぶ)は、 helloという名前の拡張モジュールを生成します。このモジュールには、単一の関数greet()が含まれています。

#include <Python.h>
#include <stdio.h>

#if PY_MAJOR_VERSION >= 3
#define IS_PY3K
#endif

static PyObject *hello_greet(PyObject *self, PyObject *args)
{
    const char *input;
    if (!PyArg_ParseTuple(args, "s", &input)) {
        return NULL;
    }
    printf("%s", input);
    Py_RETURN_NONE;
}

static PyMethodDef HelloMethods[] = {
    { "greet", hello_greet, METH_VARARGS, "Greet the user" },
    { NULL, NULL, 0, NULL }
};

#ifdef IS_PY3K
static struct PyModuleDef hellomodule = {
    PyModuleDef_HEAD_INIT, "hello", NULL, -1, HelloMethods
};

PyMODINIT_FUNC PyInit_hello(void)
{
    return PyModule_Create(&hellomodule);
}
#else
PyMODINIT_FUNC inithello(void)
{
    (void) Py_InitModule("hello", HelloMethods);
}
#endif

gccコンパイラでファイルをコンパイルするには、お好みのターミナルで次のコマンドを実行します。

gcc /path/to/your/file/hello.c -o /path/to/your/file/hello

以前に書いたgreet()関数を実行するには、同じディレクトリにファイルを作成し、 hello.py

import hello          # imports the compiled library
hello.greet("Hello!") # runs the greet() function with "Hello!" as an argument

開いているファイルをCの拡張機能に渡す

開いているファイルオブジェクトをPythonからC拡張コードに渡します。

PyObject_AsFileDescriptor関数を使用してファイルを整数ファイル記述子に変換することができます:

PyObject *fobj;
int fd = PyObject_AsFileDescriptor(fobj);
if (fd < 0){
    return NULL;
}

整数ファイル記述子をPythonオブジェクトに変換するには、 PyFile_FromFd使用しPyFile_FromFd

int fd; /* Existing file descriptor */
PyObject *fobj = PyFile_FromFd(fd, "filename","r",-1,NULL,NULL,NULL,1);

C ++とBoostを使用したC拡張

これは、C ++とBoostを使用したC拡張の基本的な例です。

C ++コード

hello.cppに入れられたC ++コード:

#include <boost/python/module.hpp>
#include <boost/python/list.hpp>
#include <boost/python/class.hpp>
#include <boost/python/def.hpp>

// Return a hello world string.
std::string get_hello_function()
{
   return "Hello world!";
}

// hello class that can return a list of count hello world strings.
class hello_class
{
public:

   // Taking the greeting message in the constructor.
   hello_class(std::string message) : _message(message) {}

   // Returns the message count times in a python list.
   boost::python::list as_list(int count)
   {
      boost::python::list res;
      for (int i = 0; i < count; ++i) {
         res.append(_message);
      }
      return res;
   }
   
private:
   std::string _message;
};


// Defining a python module naming it to "hello".
BOOST_PYTHON_MODULE(hello)
{
   // Here you declare what functions and classes that should be exposed on the module.

   // The get_hello_function exposed to python as a function.
   boost::python::def("get_hello", get_hello_function);

   // The hello_class exposed to python as a class.
   boost::python::class_<hello_class>("Hello", boost::python::init<std::string>())
      .def("as_list", &hello_class::as_list)
      ;   
}

これをPythonモジュールにコンパイルするには、Pythonヘッダとboostライブラリが必要です。この例は、Python 3.4とgccを使用してUbuntu 12.04で作成されました。 Boostは多くのプラットフォームでサポートされています。 Ubuntuの場合、必要なパッケージは以下を使用してインストールされました:

sudo apt-get install gcc libboost-dev libpython3.4-dev

ソースファイルを.soファイルにコンパイルします。このファイルは、後でPythonパス上にあれば、モジュールとしてインポートできます。

gcc -shared -o hello.so -fPIC -I/usr/include/python3.4 hello.cpp -lboost_python-py34 -lboost_system -l:libpython3.4m.so

example.pyファイルのpythonコード:

import hello

print(hello.get_hello())

h = hello.Hello("World hello!")
print(h.as_list(3))

次に、 python3 example.pyは次のように出力します:

Hello world!
['World hello!', 'World hello!', 'World hello!']


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow