1

研究上の理由でCとPythonを組み合わせようとしていますが、コードに問題があります。チュートリアルのコードを使用しましたが、Pythonファイルを取得するためのコードが機能していないようです。コードは次のとおりです。

helloClass.py

def sayHello(name):
return "Hello " + name + "!"

main.c

int main(int argc, const char * argv[]) {
char name[50];
printf("What's your name?\n");
fgets(name, 64, stdin);
char *answer = NULL;
PyObject *modname, *mod, *mdict, *func, *stringarg, *args, *rslt;
Py_Initialize();
PySys_SetPath(Py_GetPath()); 
modname = PyString_FromString("helloClass");
mod = PyImport_Import(modname);// Here mod = null because it can´t find it.
if (mod){
    mdict = PyModule_GetDict(mod);
    func = PyDict_GetItemString(mdict, "sayHello");
    if (func){
        if (PyCallable_Check(func)) {
            stringarg = PyString_FromString(name);
            args = PyTuple_New(1);
            PyTuple_SetItem(args, 0, stringarg);
            rslt = PyObject_CallObject(func, args);
            if (rslt) {
                answer = PyString_AsString(rslt);
                Py_XDECREF(rslt);
            }
            Py_XDECREF(stringarg);
            Py_XDECREF(args);
        }
        Py_XDECREF(mdict);
        Py_XDECREF(func);
    }
    Py_XDECREF(modname);
    Py_XDECREF(mod);
}
printf("%s", answer);
answer = NULL; }
4

1 に答える 1

1

ここには完全な答えを与えるのに十分な情報はありませんが、基本的な問題はほぼ確実helloClass.pyにモジュール検索パスのどこにも到達しPyImport_Importないため、見つけることができません。

たとえば、main実行可能ファイルをのような場所にビルドしている~/Library/Developer/Xcode/DerivedData/Hello/Build/Products/Release/helloが、そこにコピーしていないhelloClass.py場合があります。または、そこにコピーしているかもしれませんが、モジュールパスに同等のものがありdirname $0ません。または…まあ、百万の可能性がありますが、答えはすべての場合で同じです:

  1. 実行可能ファイルとPythonファイルがインストールされる場所を特定します。

  2. その知識から適切な(おそらく相対的な)パスを構築します。

  3. パスがモジュールパスに追加されていることを確認してください。

Pythonがモジュールを検索する方法の正確な詳細はバージョンによって異なりますが、基本的な考え方はステートメント(またはインポートシステムに準拠する3.3バージョン)で説明されておりimport多く場合に何かを追加するだけです。sys.path

(Unixコマンドライン実行可能ファイルだけでなく.appバンドルを構築している場合は、これに対する標準的な答えがあります。.pyファイルを標準の場所に貼り付け、CocoaまたはCoreFoundation APIを使用してパスを取得し、次にそれを使用します。しかし、それはここでは関係がないようです。)


https://github.com/Eduardof0nt/help.gitでアップロードしたプロジェクトを見てください:

あなたはhelloClass.pyどこにもコピーしていません。あなたはそれをどこにコピーしたいかを決める必要があります、そしてそれはあなたが物事をどのように展開したいかに完全に依存します。Hello Python!ただし、デバッグの目的で、テスト可能なものを取得するために、実行可能ファイル(build/Debugまたは)と一緒に配置することができますbuild/Release。それを行うには:

  • プロジェクトナビゲータでプロジェクトを選択します。
  • 表示されるプロジェクトビューの左側のサイドバーでターゲットを選択します。
  • [ビルドフェーズ]タブを選択します。
  • [ビルドフェーズの追加]ボタンをクリックします。
  • ファイルのコピーフェーズを追加します。
  • 宛先をProductsDirectoryに設定します。
  • helloClass.pyプロジェクトナビゲータからビルドフェーズにドラッグします。

これで、ビルド時に出力を見ると(「すべて」と「すべてのメッセージ」をオンにすると)、「Link build / Debug /HelloPython」の直後に「Copybuild/Debug/helloClass.py」が表示されます。 !"。そして、そのディレクトリ内を見ると、2つのファイルが並んで表示されます。

しかし、それはあなたの問題全体を解決するわけではありません。Pythonが使用/wherever/you/started/build/Debugするものにはならないからです。sys.pathこれを回避する最も簡単な方法は、Py_SetProgramName(argv[0])の直前と直後にPy_Initialize()電話をかけることPySys_SetArgvEx(argc, argv, 1)です。これはユースケースにとって正しいことではないかもしれませんが、PythonをSOに埋め込むことの詳細をすべて説明することはできないため、ドキュメントを読んで、これらすべてが何をするのかを理解する必要があります。答え。

このようなことを学ぼうとしている間、おそらくデバッグをしたいと思うでしょう。たとえば、同等printf(path=%s\n", Py_GetPath())のものを確認したり、に何が含まれているかを確認したりできます。しかし、実際には、Xcodeデバッガーを使用する必要があります。ブレークポイントを追加して、実行時にこのようなことを試してください。sys.pathPyObject_Print(mod, stdout, 0)mod

これの多くはPythonインタープリターの拡張と埋め込みで説明されており、実際にそれを読む必要があります。代替品はありません。( Python / C APIリファレンスマニュアル全体を読む必要はありませんが、完了する前に、多くのことを読み、検索が上手になるでしょう。)ただし、Pythonの埋め込みははるかに少ないためです。拡張するよりも一般的ですが、ドキュメントには実際に必要なものがすべて含まれているわけではないため、使用しているチュートリアルでやなどがカバーされていない場合PySys_*Py_GetPath、最初に、より適切なチュートリアルを見つける必要があります。

于 2013-02-19T21:22:07.227 に答える