LoginSignup
31
23

More than 5 years have passed since last update.

pybind11入門(1)

Posted at

Open3DやDlibのソースコードを読んでいるとpybind11という何やらすてきなものを使ってPythonのライブラリを作っているので試してみた。

準備

cmakeを使用します。pybind11はヘッダーだけのライブラリで、github (https://github.com/pybind/pybind11/releases) などからダウンロードして以下のようなディレクトリ配置にします。

project top
|- CMakeLists.txt
|- pybind11/ 
|- mymodule.cpp

ソースコード

mymodule.cpp には以下のように書きます。

#include <pybind11/pybind11.h>

int add(int a, int b)
{
    return a + b;
}

PYBIND11_MODULE(mymodule, m)
{
    m.doc() = "my test module";
    m.def("add", &add, "add two numbers");
}

PYBIND11_MODULE というマクロを使用してPythonモジュールを作成できます。引数の1つめのmymoduleはモジュールの名前で最終的に作成するライブラリのファイル名と揃える必要があります。 (mymodule.cpython-37m-x86_64-linux-gnu.so のような名前になる場合は mymodule)

2つ目の引数 m はマクロ内でのみ使用するもので、その後のように m.def を使用して関数を登録します。

これをビルドする際には次のような CMakeLists.txt を作成します。

cmake_minimum_required(VERSION 3.2)
project(pybind_test VERSION 0.1.0)

add_subdirectory(pybind11)
pybind11_add_module(mymodule mymodule.cpp)

このままビルドするとデフォルトのPythonが使用されます。vritualenvやcondaで作った特定のバージョンのPython環境に対してビルドしたい場合は事前にその環境をactivateするか、 cmake -DPYTHON_EXECUTABLE=path/to/python .. のように指定します。 LinuxでPython3.7に対してビルドするとmymodule.cpython-37m-x86_64-linux-gnu.so というファイルができます。これをPYTHONPATHが通っている場所(例えばカレントディレクトリ)におけばimportできます。

import mymodule
mymodule.add(1, 10)
>> 11

ソースファイルの分割

プロジェクトが大きくなったり、もともとあるC/C++のコードを利用したいというときに全てのコードを mymodule.cpp に書くわけには行きません。ソースコードを複数に分割する場合には次のようにします。

project top
|- CMakeLists.txt
|- pybind11/ 
|- mymodule.cpp
|- lib.cpp
|- lib.hpp
lib.hpp
int add(int a, int b);
lib.cpp
#include "lib.hpp"

int add(int a, int b)
{
    return a + b;
}
mymodule.cpp
#include <pybind11/pybind11.h>
#include "lib.hpp"

PYBIND11_MODULE(mymodule, m)
{
    m.doc() = "my test module";
    m.def("add", &add, "add two numbers");
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.2)
project(pybind_test VERSION 0.1.0)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

add_subdirectory(pybind11)

add_library(test lib.cpp)

pybind11_add_module(mymodule mymodule.cpp)
target_link_libraries(mymodule PRIVATE test)

ポイントはadd_libraryを使用してPythonと関係ないライブラリを作成したあと、target_link_librariesでpybind11で作ったmoduleとそれを結合します。もちろんpybind11_add_moduleで全てのソースファイルを指定しても良いのですが、こちらのほうが通常のC/C++用ライブラリとPython用ライブラリの両方ができるので何かと便利だと思います。

参考

公式doc: https://pybind11.readthedocs.io/en/stable/index.html

31
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
23