C言語とPythonスクリプトを連携させたく、組込んでみたのですが、その際に役に立ったのでURLリストを作成しておきます。
参考サイト
Pythonスクリプトを同的に変更する
まずは、APIの『純粋な埋め込み』を実装してみました。単純なCソースからのPythonスクリプトのコール処理は比較的簡単に実装できました。
ただ、Pythonは1度インタプリタにかけてしまうとメモリ上に残っているので、ソースファイルを修正してもリロードしてくれません。そこで、以下のように修正し、リロード(PyImport_ReloadModule)処理を入れてみました。”end”文字列が入力されるまで繰返しmultiply.pyスクリプトを処理します。
#include <stdio.h>
#include <Python.h>
extern int sub_main(int argc, char *argv[]);
extern char *readfile(char filename[]);
#define PARAMLEN 3
int
main(int argc, char *argv[])
{
int ret = -1 ;
char cmd[PARAMLEN][32] = {"call","multiply","multiply"};
char moji[64];
argc = PARAMLEN;
argv[0] = &cmd[0];
argv[1] = &cmd[1];
argv[2] = &cmd[2];
// 初期化
Py_Initialize();
while(1){
ret = sub_main(argc, argv); // multiply.py処理
printf("----------------------------------\n", ret);
printf("result is %d\n", ret);
printf("----------------------------------\n", ret);
scanf("%s", moji);
if( 0 == strcmp(moji, "end")) // "end" で終了
break;
}
// 終了処理
Py_Finalize();
return ret;
}
int
sub_main(int argc, char *argv[])
{
PyObject *pName, *pModule, *pDict, *pFunc, *pModule2, *pModulePrm; // iwakura Add
PyObject *pArgs, *pValue;
int i;
char *p_buf;
pName = PyString_FromString(argv[1]);
/* Error checking of pName left out */
pModule = PyImport_Import(pName);
pModule2 = PyImport_ReloadModule(pModule); // iwakura Add
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule2, argv[2]);
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(argc - 3);
for (i = 0; i < argc - 3; ++i) {
pValue = PyInt_FromLong(atoi(argv[i + 3]));
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
Py_DECREF(pModule2); // iwakura Add
fprintf(stderr, "Cannot convert argument\n");
return 1;
}
// pValue reference stolen here:
PyTuple_SetItem(pArgs, i, pValue);
}
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL) {
printf("Result of call: %ld\n", PyInt_AsLong(pValue));
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
Py_DECREF(pModule2); // iwakura Add
PyErr_Print();
fprintf(stderr,"Call failed\n");
return 1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
Py_DECREF(pModule2); // iwakura Add
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
return 1;
}
return 0;
}
multiply.pyは参考元ソースそのままです。a,bのパラメータを修正すると、動的に処理内容が変更されているのが分かります。
#def multiply(a,b):
def multiply():
a=2
b=5
print "Will compute", a, "times", b
c = 0
for i in range(0, a):
c = c + b
return c