LinuxでC呼び出しPython
5324 ワード
説明CプログラムでPythonを呼び出すには、ヘッダファイルPythonを含める.ええ、Pythonのためです.hはデフォルトの検索パスにありません.ここでは2つの方法で解決します.1.プログラムにPythonを含める.hのパス:
PS:これはデフォルトのパス2です.リンク時にgccのパラメータを加える:
Makefileの作成
ここでは、Makefileの作成を参照してください.
ここでpython 2.7.soダイナミックライブラリへのリンク
最も簡単な呼び出し
このようなPythonの呼び出しはlow levelと呼ばれ、Cプログラムで簡単なPython文の呼び出しに適用されます.
さらなる呼び出し
この呼び出しはhighlevelと呼ばれ、より多くの場合、自分で作成した、システムのモジュールと関数、サードパーティ製ライブラリを呼び出す方法が必要です.
test.c
1.py:
PS:名前はつけないでください.py、Pythonにはtestモジュールが付属しているので、導入後は自分で作成した関数が見つかりません
パラメータを含む呼び出し
パラメータを含む呼び出しは複雑で,パラメータスタックなどに加えてCデータ型とPythonデータ型の変換の問題がある.ここでは簡単な使い方をしただけです.
1つの例(詳細は後述):
test.c
1.py:
主関数の違いはパラメータのスタック(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の関数に戻り値がある場合は、関数を呼び出す方法を次のように変更します.
ドキュメント
以上は簡単に紹介しただけで、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
#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