0

C++ から Django 関数を呼び出し、その出力を C++ コードで取得する必要があります。ご存じのように、Django は、必要な関数を最初のパラメーターとして使用し、その後に引数を指定して Manage.py Python スクリプトを呼び出すことによって使用されます。

現在、JSON 形式の文字列を返す「test」という名前のテスト関数があります。

したがって、私が電話すると:

    python manage.py test

私は次のようになります:

   {'products': [{'id': 125, 'label': 'Robin'}, {'id': 4, 'label': 'Robinou'}]}

これを cpp で取得するには、次のことができます。

   system(python path.../manage.py test);

出力をキャッチします。しかし、私はそれが好きではありません。Boost.Python も使用できます。私も好きじゃない。

サイズと速度を考慮して、これを C++/Python.h でのみ実行できるようにしたいと考えています。

これは私が実行しているmanage.pyです:

   import os
   import sys

   sys.path.append('C:\ds')

   if __name__ == "__main__":
       os.environ.setdefault("DJANGO_SETTINGS_MODULE", "frontoffice.settings")

   from django.core.management import execute_from_command_line
   execute_from_command_line(sys.argv)

を追加するprint sys.argvと、次の出力が得られます: ['manage.py', 'test'].

だから私は厄介な方法でそれを行うことができました:

   bool initPython()
   {
       Py_Initialize();

       int check = 0;

       check = PyRun_SimpleString("import sys");
       check = PyRun_SimpleString("import os");
       check = PyRun_SimpleString("sys.path.append('C:\\ds')");
       check = PyRun_SimpleString("os.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"frontoffice.settings\")");
       check = PyRun_SimpleString("from django.core.management import execute_from_command_line");

       if(check == 0) return true;
       else return false;
   }

   std::string execPythonCommand(std::string cmd)
   {
       std::string command = std::string("robin = ['dontreallycarewhatitis',       '").append(cmd).append("']");

       PyRun_SimpleString(command.c_str());
       PyRun_SimpleString("execute_from_command_line(robin)");
   }

派手なものはありません。クロスプラットフォームであるという利点がありますが、出力をキャッチするのは面倒なので、機能しますが、私が探しているものではありません。execute_from_comand_line コマンドの出力を直接取得できるようにしたいと考えています。

これが私がこれまでに思いついたものです。initPython() を実行した後:

    PyObject* executeCmd = PyImport_Import(PyString_FromString("django.core.management"));
    PyObject* executeFunc = PyObject_GetAttrString(executeCmd, "execute_from_command_line");

    std::cout << "Imported function." << " isNULL: " << (executeFunc == NULL) << " isExecutable: " << PyCallable_Check((executeFunc)) << std::endl;

だから私は execute_from_command_line 関数の Cpp オブジェクトを取得することができました - そしてそれは呼び出し可能です。ここがややこしいところです。どうやって呼ぶの?

Python Documentation によると、sys.argv はリストです。そこで、まったく同じものを再作成して呼び出してみました:

    PyObject* pRobin = PyList_New(2);
    PyObject* pString = PyString_FromString("test");
    PyObject* pString0 = PyString_FromString("manage.py");
    PyList_Append(pRobin,pString0);
    PyList_Append(pRobin,pString);

    PyObject* pValue = PyObject_CallObject(executeFunc, pRobin);
    //PyObject* pValue = PyObject_CallFunctionObjArgs(executeFunc, pRobin, NULL); //Doesn't work either

今、私はすべてを試しました。リストの代わりにタプルを使用する PyObject_CallObject、CallFunction、CallFunctionObjArgs、および PyErr_Print() は私に明示的なものを何も与えません。私はPythonの専門家ではなく、この問題に苦しんでいます。テスト ルーチンの出力 JSON 文字列を格納する pValue を取得するにはどうすればよいですか?

ご参考までに:

    >>> inspect.getargspec(django.core.management.execute_from_command_line)
    ArgSpec(args=['argv'], varargs=None, keywords=None, defaults=(None,))

やがて、manage.py xxx (xxx はコマンド) を頻繁かつ迅速に実行する必要があるため、面倒な stdio キャッチを行うよりも C/API を使用したいと考えています。

参考までに、私は VS2012、Windows 8、Python 2.7、および PostGRE を使用しています。どんなアイデアでも大歓迎です。ありがとう!

4

1 に答える 1

2

C++ から Python を呼び出すことについては何も知りませんが、Python で動的に管理コマンドを呼び出す方法は、django.core.management.call_command. それを使用すると、物事が簡単になる場合があります。

于 2013-06-11T09:20:16.710 に答える