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