LinuxでC呼び出しPython

5324 ワード

説明CプログラムでPythonを呼び出すには、ヘッダファイルPythonを含める.ええ、Pythonのためです.hはデフォルトの検索パスにありません.ここでは2つの方法で解決します.1.プログラムにPythonを含める.hのパス:
#include 

PS:これはデフォルトのパス2です.リンク時にgccのパラメータを加える:
-I/usr/include/python2.7/

Makefileの作成
ここでは、Makefileの作成を参照してください.
CC = gcc
CFLAGS =  -g -Wall

TARGET = test
	
INC = -I/usr/include/python2.7/
LIB = -L/usr/lib -lpython2.7

all: clean $(TARGET)

test: test.o
	$(CC) -o $(TARGET) test.o $(LIB)
test.o: test.c
	$(CC) -c test.c $(CFLAGS)

clean:
	rm -rf *.o $(TARGET)

ここでpython 2.7.soダイナミックライブラリへのリンク
最も簡単な呼び出し
このようなPythonの呼び出しはlow levelと呼ばれ、Cプログラムで簡単なPython文の呼び出しに適用されます.
#include "/usr/include/python2.7/Python.h"

void
deal_error(const char *str)
{
	fprintf(stderr, "%s
", str); exit(EXIT_FAILURE); } int main() { // Python // C Python Py_Initialize(); if(!Py_IsInitialized()) { deal_error("Cannot init Python interpreter!"); } // Python PyRun_SimpleString("print 'Hello World'"); return 0; }

さらなる呼び出し
この呼び出しはhighlevelと呼ばれ、より多くの場合、自分で作成した、システムのモジュールと関数、サードパーティ製ライブラリを呼び出す方法が必要です.
test.c
#include "/usr/include/python2.7/Python.h"

void
deal_error(const char *str)
{
	fprintf(stderr, "%s
", str); exit(EXIT_FAILURE); } int main() { PyObject *p_name = NULL, *p_module = NULL, *p_dict = NULL, *p_func = NULL; // Python // C Python Py_Initialize(); if(!Py_IsInitialized()) { deal_error("Cannot init Python interpreter!"); } // Python // Python // , PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append('./')"); // Python // , py p_name = PyString_FromString("1"); p_module = PyImport_Import(p_name); if(!p_module) { deal_error("Cannot load the module!"); } // p_dict = PyModule_GetDict(p_module); if(!p_dict) { deal_error("Cannot get the dict"); } // p_func = PyDict_GetItemString(p_dict, "hello"); if(!p_func || !PyCallable_Check(p_func)) { deal_error("Cannot find the function"); } // PyObject_CallObject(p_func, NULL); // Py_DECREF(p_name); Py_DECREF(p_module); Py_DECREF(p_dict); Py_DECREF(p_func); // Python Py_Finalize(); return 0; }

1.py:
PS:名前はつけないでください.py、Pythonにはtestモジュールが付属しているので、導入後は自分で作成した関数が見つかりません
#!/usr/bin/env python
#-*- coding: utf-8 -*-

def hello():
    print 'hello'

パラメータを含む呼び出し
パラメータを含む呼び出しは複雑で,パラメータスタックなどに加えてCデータ型とPythonデータ型の変換の問題がある.ここでは簡単な使い方をしただけです.
1つの例(詳細は後述):
test.c
#include "/usr/include/python2.7/Python.h"

void
deal_error(const char *str)
{
	fprintf(stderr, "%s
", str); exit(EXIT_FAILURE); } int main() { PyObject *p_name = NULL, *p_module = NULL, *p_dict = NULL, *p_func = NULL, *p_args = NULL; // Python // C Python Py_Initialize(); if(!Py_IsInitialized()) { deal_error("Cannot init Python interpreter!"); } // Python // Python // , PyRun_SimpleString("import sys"); PyRun_SimpleString("sys.path.append('./')"); // Python // , py p_name = PyString_FromString("1"); p_module = PyImport_Import(p_name); if(!p_module) { deal_error("Cannot load the module!"); } // p_dict = PyModule_GetDict(p_module); if(!p_dict) { deal_error("Cannot get the dict"); } // p_func = PyDict_GetItemString(p_dict, "add"); if(!p_func || !PyCallable_Check(p_func)) { deal_error("Cannot find the function"); } p_args = PyTuple_New(2); PyTuple_SetItem(p_args, 0, Py_BuildValue("i", 3)); PyTuple_SetItem(p_args, 1, Py_BuildValue("i", 4)); // PyObject_CallObject(p_func, p_args); // Py_DECREF(p_name); Py_DECREF(p_module); Py_DECREF(p_dict); Py_DECREF(p_func); // Python Py_Finalize(); return 0; }

1.py:
#!/usr/bin/env python
#-*- coding: utf-8 -*-

def add(a, b):
    print a+b

主関数の違いはパラメータのスタック(addに戻り値がないため、議論する場合がある)であることに気づき、まずPyTuple_Newは新しいパラメータの元祖であり、この関数のパラメータは構築する元祖の長さである.
PyObject* PyTuple_New( Py_ssize_t len);  
その後、各パラメータを設定し、PyTuple_を利用します.SetItem
int PyTuple_SetItem( PyObject *p, Py_ssize_t pos, PyObject *o);
pは設定するパラメータの元祖で、つまりさっき新しく作ったもので、posはA要素を設定する位置で、oは追加した要素の値で、ここでPy_に関連しますBuildValueの使い方
Py_BuildValueは、主に整数、浮動小数点数、文字列などのフォーマットされたパラメータタイプを提供します.具体的な使い方は以下の通りです.http://docs.python.org/release/1.5.2p2/ext/buildValue.html
Pythonの関数に戻り値がある場合は、関数を呼び出す方法を次のように変更します.
        int ret;
	PyObject *p_retval = NULL;

	p_retval = PyObject_CallObject(p_func, p_args);
	PyArg_Parse(p_retval, "i", &ret);

ドキュメント
以上は簡単に紹介しただけで、PythonとCのタイプは互いに変換するのが面倒で、詳細な関数:
CタイプからPythonタイプを生成:
http://docs.python.org/release/1.5.2p1/api/node24.html
PythonをCタイプに変換:
http://docs.python.org/2/c-api/concrete.html
C Pythonの公式ドキュメントを呼び出す:
http://docs.python.org/2/c-api/index.html