2023/3/30
製品
カテゴリー
タグ
674 Views
ctypesを利用したC+Python混合環境で使用する(Linux)
Linux環境下でctypesを利用したPythonアプリ+CライブラリへのDT+導入手順例について説明します。
Contents
サンプルドライバ
サンプルドライバは以下よりダウンロードください。
接続方式 | ダウンロード |
---|---|
Ethermet(ドライバ対応方式) | ダウンロード |
ファイル書き出し(ドライバ対応方式) | ダウンロード |
なお、c部分のドライバは通常のサンプルドライバと同様になります。
全体のイメージ
上記はEthernet接続の場合の全体イメージ図です。PythonコードからはDTTestPointDriver.pyを介して、その他C/C++の処理はDT+ドライバを共有ライブラリにビルドし、それをリンクする形で利用します。
ファイル書き出しの場合は「dt_datawriting_drv.c」「dt_datawriting_drv.so」としてLinux上にバイナリ形式のファイルとしてレポートデータを保存します。
構築手順
①DT+プロジェクトの作成
通常通りプロジェクトを作成します。なお、サンプルドライバはいずれもドライバ対応となっております。
CライブラリのソースとPythonソースの両方をDT+プロジェクトに追加します。
②C言語ドライバの変更・ビルド
C言語ドライバファイルの変更点は通常のチュートリアルと同様です。以下のチュートリアルページをご参照ください。
修正後、C言語ドライバを共有ライブラリとしてビルドします。
"xxx"は"datawriting"または"ether"になります。適時読み替えてご利用ください。
$cd ~/root/src/lib/dtxlib
$ls
$DtTestPointDriver.py dt_xxx_drv.c
$gcc -fPIC --shared dt_xxx_drv.c -o libdt_lib.so
または
$g++ -fPIC --shared dt_xxx_drv.cpp -o libdt_lib.so
$ls
$DtTestPointDriver.py dt_xxx_drv.c libdt_lib.so
生成する共有ライブラリ名は任意の名前で構いません。ただし共有ライブラリ命名規則に従いファイル名先頭は"lib"、拡張子を"*.so"となるよう指定してください。
③DTドライバ(*so)を他の共有オブジェクト、実行ファイルに組み込む
他のC共有ライブラリに組み込む場合は以下の通りです。例ではctypes_sampleがpythonで使用されるCライブラリと想定しています。
Makefile等に以下の処理を追加してください。
①DT+共有ライブラリ(libdt_lib.so)を他のライブラリフォルダ、またはビルド対象フォルダ直下にコピー
②gccコマンドまたはMakefile等にDT+共有ライブラリのリンクを追加
以下はコマンドライン操作でのgccコマンドからのビルドの例を記載します。
$cp .libdt_lib.so ~/yourlibpath/ctypes_sample
$cd ~/yourlibpath/ctypes_sample
$ls
$DT_ctypes_sample.h ctypes_sample.c ctypes_sample.h libdt_lib.so
$gcc -fPIC --shared ctypes_sample.c -o libctypes_sample.so -ldt_lib -L./
$ls
$DT_ctypes_sample.h ctypes_sample.c ctypes_sample.h libctypes_sample.so libdt_lib.so
"-l"オプションがリンクする共有ライブラリ、"-L"が共有ライブラリのパスの指定となります。"-l"で指定する際、接頭語の"lib"、拡張子は除いた形での指定となります。
Makefileに追加する場合は一般的なMakefileであれば"LDFLAGS"、"LIBS"などに追記ください。
CMakeに追加する場合は対象のtarget_link_librariesにDT+共有ライブラリを追記してください。
④DT+Pythonドライバ、DT+共有ライブラリのリンク
PythonアプリにDtTestPointDriver.pyを組み込みます。この際、DtTestPointDriver.py並びにDT+を適用した独自の共有ライブラリからDT+共有ライブラリが参照できるよう、以下の設定を行ってください。
Pythonのcdll.LoadLibraryに直接パスを指定する
Pythonアプリへの適用についてはctypesを利用する場合、直接パスの指定が可能です。
import struct
import ctypes
DtTestPoint_DriverLib = ctypes.cdll.LoadLibrary("./libdt_lib.so") # Customize its
pythonファイルから直接DT+共有ライブラリを参照する場合は、DtTestPointDriver.pyの上記の参照パスを直接変更してください。可変にする場合は以下のような指定も可能です。
import os
path = os.path.dirname(os.path.realpath(__file__))
DtTestPoint_DriverLib = DtTestPoint_DriverLib("%slibdt_lib.so" % path)
環境変数に追加して実行する
自作の共有ライブラリに組み込む場合、共有ライブラリ間のリンクは保証されないためDT+共有ライブラリが参照エラーになります。環境変数にDT+共有ライブラリを追加してご利用ください。
$cp .*.so ~/yourpython
$cd ~/yourPython
$ls
$libctypes_sample.so libdt_lib.so main.py testlib src
$LD_LIBRARY_PATH=. python3 main.py
または
$ls
$libctypes_sample.so libdt_lib.so main.py testlib src
$export LD_LIBRARY_PATH=/home/foo/dt_libPath/
$python3 main.py
なお、環境変数を常に設定しておく場合は~./bash_profileや~/.bashrcにLD_LIBRARY_PATHとして指定してください。
システム全体の共有ライブラリ参照パスに追加する
環境変数ではなくシステム全体に対してライブラリの追加を適応する場合は、/etc/ld.so.confにDT+共有ライブラリのパスを追記してください。
$sudo vi /etc/ld.so.conf
/usr/local/lib
/usr/lib
…
/home/foo/dt_libPath/ ←追記
:wq
$sudo ldconfig
⑤テスト実行し、レポートデータを取得
Pythonアプリを実行します。Ethernet接続やファイル書き出し接続の設定詳細は本QAでは割愛します。上記チュートリアルをご参照ください。
取得したテストレポート上でpythonとCのレポート出力が確認できれば完了となります。