モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

目次目次を開く/閉じる

Python から C ライブラリを利用 (ctypes)

モーダルを閉じる

ステッカーを選択してください

お支払い手続きへ
モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2018/06/04
最終更新最終更新
2021/08/02
記事区分記事区分
一般公開

目次

    プログラミング教育者。ScratchやPythonを教えています。

    FFI (Foreign Function Interface) の一つである ctypes を利用すると、C 言語のライブラリを Python から利用できます。サンプルコードを記載します。

    libm の sqrt を利用する例

    main.py

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    from ctypes import CDLL, c_double
    from ctypes.util import find_library
    
    def Main():
        libm = CDLL(find_library('m'), use_errno = True)
        libm.sqrt.argtypes = [c_double]
        libm.sqrt.restype = c_double
        print libm.sqrt(121)
    
    if __name__ == '__main__':
        Main()
    

    実行例

    $ python main.py
    11.0
    

    libc 経由でシステムコールを利用する例

    システムコールは libc 経由で利用できます。例えば、poll を Python から libc 経由で利用する例は以下のようになります。

    main.py

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    
    from ctypes import CDLL, Structure, POINTER, c_short, c_int
    from ctypes.util import find_library
    
    class Pollfd(Structure):
        # $ man 2 poll
        # struct pollfd {
        #     int   fd;         /* file descriptor */
        #     short events;     /* requested events */
        #     short revents;    /* returned events */
        # };
        _fields_ = [("fd", c_int),
                    ("events", c_short),
                    ("revents", c_short)]
        def _init_(self, fd, events, revents):
            self.fd = fd
            self.events = events
            self.revents = revents
    
    OnePollfdArrayType = Pollfd * 1
    POLLIN = 0x0001 # https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/poll.h
    POLLERR = 0x0008
    POLLHUP = 0x0010
    POLLNVAL = 0x0020
    
    def Main():
        libc = CDLL(find_library('c'), use_errno = True)
    
        # ファイルディスクリプタ 0 を監視
        fds = OnePollfdArrayType(Pollfd())
        fds[0].fd = 0
        fds[0].events = POLLIN 
    
        # C 言語の型を引数と返り値に関して設定
        # $ man 2 poll
        # int poll(struct pollfd *fds, nfds_t nfds, int timeout);
        libc.poll.argtypes = [POINTER(Pollfd), c_int, c_int]
        libc.poll.restype = c_int
    
        while True:
            n = libc.poll(fds, 1, 5000)
            if n < 0:
                raise Exception("poll")
            elif n == 0:
                print "no input"
            else:
                for ifd in range(1):
                    if fds[ifd].revents & (POLLERR | POLLHUP | POLLNVAL):
                        raise Exception("poll %d" % ifd)
                    elif fds[ifd].revents & POLLIN:
                        print "input from fd%d: %s" % (ifd, raw_input())
    
    if __name__ == '__main__':
        Main()
    

    実行例

    $ python main.py
    aaa ←エンター
    input from fd0: aaa
    xxx
    input from fd0: xxx
    no input  ←5秒経過
    no input
    

    その他の連携方法

    C/C++ 動的ライブラリを Python から利用する方法としては ctypes 以外にも Python 標準の <Python.h>Boost.Python があります。

    例えば ModernGLでは libGL.so.1 を C++ 側で読み込むために <Python.h> が利用されています。OpenRAVE では Boost.Python が利用されています

    hello.cpp

    #include <boost/python.hpp>
    
    char const* greet() {
        return "hello, world";
    }
    
    BOOST_PYTHON_MODULE(hello) {
        using namespace boost::python;
        def("greet", greet);
    }
    

    ldconfig で動的リンク対象のライブラリがインストールされていることを確認します。

    /sbin/ldconfig -p | grep python
    
    dpkg -S /usr/lib/x86_64-linux-gnu/libboost_python.so  #=> libboost-python1.62-dev
    dpkg -S /usr/lib/x86_64-linux-gnu/libpython2.7.so  #=> libpython2.7-dev
    

    ビルドコマンド例

    g++ -shared -fPIC -lboost_python -lpython2.7 -I/usr/include/python2.7 -o hello.so hello.cpp
    

    実行例

    In [1]: import hello
    
    In [2]: hello.greet()
    Out[2]: 'hello, world'
    
    Likeボタン(off)0
    詳細設定を開く/閉じる
    アカウント プロフィール画像

    プログラミング教育者。ScratchやPythonを教えています。

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    >>さらに詳しくステッカーを贈る
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。

      ログインする

      関連記事

      • cmake で ccache を有効化するための設定
        YOCTO Linux で開発している場合など、ビルド速度が開発効率にそのまま影響する際は ccache (compiler cache) で C/C++ ビルドを高速化することを考えます。cmakeと併用する場合の設定およびコマンド例を記載します。 インストール sudo apt install ccache 以下のバイナリファイルに加えて $ w
        AWS NinjaAWS Ninja10/22/2022に更新
        いいねアイコン画像0
      • 低レイヤーネットワークプログラミングに関する雑多な知識
        TCP/IP モデルのうちトランスポート層ではなく、インターネット層およびネットワークインターフェイス層のパケット (正確には PDU) を扱う低レイヤープログラミングの雑多なテクニックをまとめます。『ルーター自作でわかるパケットの流れ』などを参考にしています。バックアップ目的で書籍のサンプルコードをホスティングしました。 検証環境
      • ファイルディスクリプタ関連のシステムコールのサンプルコード (C 言語)
        ファイル記述子 (File Descriptor) に関連するシステムコールを利用した C 言語のサンプルコードを記載します。 ファイルの読み書き open/close main.c #include <unistd.h> #include <fcntl.h> #include <stdio.h> int main() { int fd_r, fd_w;...
        フロックフロック9/7/2021に更新
        いいねアイコン画像0
      • C言語の資産を利用 (C++をもう一度)
        サンプルコード メルセンヌ・ツイスタなど、C言語で記述されたライブラリをC++から利用するためには extern "C" を利用します。その際、組み込みマクロ __cplusplus を利用するとC言語からもC++からも利用できるヘッダファイルを作成できます。 sub.h #ifndef SUB_H_ #define SUB_H_ #ifdef __cplu
      • C言語コード読解:size_t型とは
        サイズを表現するための符号なし整数型です。読み手にとっても、何らかのサイズを格納するための変数であることが分かりやすくなります。真偽値をbool型変数で扱う場合も同様です。 sample.cpp #include <iostream> using namespace std; int main() { size_t size = sizeof(int); cout &l...
        ほっこりさんほっこりさん4/13/2018に更新
        いいねアイコン画像0