0.環境説明
python: Python 3.9.0
gcc:gcc version 11.3.0 (GCC)
1.ctypesのドキュメント
ctypes --- Pythonのための外部関数ライブラリ
2.dllファイルの作成方法
以下のサンプルコードをpython上で実行できるようにdllファイルに変換していきます
#include <stdio.h>
#include "dll_c.h"
void doPrint(){
int value = 42;
int* address = &value;//pythonでは実行しえない処理
printf("Address: %p\n", (void*)address);
printf("Value at address: %d\n", *address);
}
extern void doPrint();
シンプルさを得るために " __declspec(dllexport)"などの記法は割愛します。
以下のコマンドでdllファイルの作成を行います
gcc -shared -fPIC dll_c.c -o dll_c.dll
3.pythonでの実行方法
import ctypes
import os
os.add_dll_directory(os.getcwd())
lib=ctypes.CDLL("dll_c")
doPrint=lib.doPrint
doPrint.restype=None
doPrint()
このコードの注意事項は
os.add_dll_directory(os.getcwd())
の部分
この処理を行わないと
FileNotFoundError: Could not find module 'dll_c' (or one of its dependencies). Try using the full path with constructor syntax.
というエラーがでてしまう。これはエラー文にあるようなフルパスを用いた方法でも同様の結果が得られる。
PATH通してるのにctypesでFileNotFoundError: Could not find module (or one of its dependencies)
上記記事を読んでなんとか解決した。
どうやらPython3.3から上記処理を行わないとエラーを吐くようになった模様。
4. 補足1(実行環境について)
インタプリンタモード、またはJupyter NotebookなどのCが実行されるべきじゃないような場所で標準出力や入力を行うとクラッシュするかフリーズする。
ctypes --- Pythonのための外部関数ライブラリ
ctypesモジュールのドキュメントより。回避策はcoutを使う(未検証)かそもそもc言語側で標準出力を使用しない、通常環境でpythonを実行以外にないと思われる
5.補足2(依存関係について)
未検証なので不正確な情報あり
オリジナルで書いたコードが追加でdllファイルを求める場合はadd_dll_directory関数でそのdllファイルがある場所を追加したほうがいい
あとがき
間違ってる箇所や追加したほうがいい箇所があった場合はコメントで書いてくれると嬉しいです。
以下に追記履歴を書きます
・gccのタグを追加(Visual Studioに回避する策も見られたので)
・コンパイルオプションにfPICを追加