質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1724閲覧

cでpython呼び出しを行った結果

uriuri

総合スコア47

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/09/14 03:28

編集2018/09/14 03:32

<参考サイト>https://blanktar.jp/blog/2013/05/use-python-by-c-lang.html

c

1#include <stdio.h> 2#include <Python.h> 3 4int main(void) 5{ 6 PyObject *pModule, *pTmp; 7 char *sTmp; 8 9 Py_Initialize(); 10 11 /* モジュールをimport */ 12 pModule = PyImport_ImportModule("python3 c.py"); 13 14 /* pythonで言う pTmp = getattr(pModule, 'func')() みたいな。 */ 15 pTmp = PyObject_CallMethod(pModule, "func", NULL); 16 17 /* PyObjectをC言語の型に変換 */ 18 PyArg_Parse(pTmp, "s", &sTmp); 19 20 printf("%s\n", sTmp); 21 22 Py_Finalize(); 23 return 0; 24}

python

1def func(): 2 print("this printed by python") 3 return ("byt, this printed by C")

gcc -fPIC python_c.c $(python3-config --cflags --ldflags)
を行い、実行ファイルa.outが作成されました
その後
./a.out
で実行した結果
□の中に
00
01
というものだけが出力されました
エラーはでていません
ldd a.outの結果
linux-vdso.so.1 => (0x00007ffef4ff2000)
libpython3.5m.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython3.5m.so.1.0 (0x00007f2fe52e8000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2fe4f1e000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f2fe4d01000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f2fe4ad8000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f2fe48be000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f2fe46ba000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f2fe44b7000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f2fe41ae000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2fe596f000)

開発環境は
ubuntu16.04 
アドバイスいただけると幸いです

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tonkun4os

2018/09/14 04:19

Cて、どれぐらい使った事が有りますか、初心者ならばもう少し勉強が必要ですねー「char *sTmp;」の意味判ってないのではー
tonkun4os

2018/09/14 04:20

因みにCに文字列型は無い事は知ってますよねー
Eki

2018/09/15 01:13

メモリアロケーションがないことについてのコメントでしょうか? 調べてみたところ、こちらのドキュメント https://docs.python.jp/3/c-api/arg.html によると「すでに存在している文字列へのポインタをその変数に記録します」とあります。 sTmp 自体のアドレスを渡している、ということからみても正しい記述と思われます。 そもそも違う意図でしたらすみません。
guest

回答1

0

ベストアンサー

こんにちは。Python 自体もあまり使ったことはなく、 Python のバインディングも使ったことはないですが、試してみたところうまくいったので報告します。

問題は、モジュールを import するパスにカレントディレクトリが含まれていないことのようです。

こちらの StackOverflow の質問 を参考にして、次のようにプログラムを修正しました。

c

1#include <stdio.h> 2 3#include <Python.h> 4 5void set_path(void) { 6 PyObject *sys = PyImport_ImportModule("sys"); 7 PyObject *sys_path = PyObject_GetAttrString(sys, "path"); 8 PyObject *dir = PyUnicode_FromString("."); 9 PyList_Append(sys_path, dir); 10} 11 12int main(void) { 13 PyObject *pModule, *pTmp; 14 char *sTmp; 15 16 Py_Initialize(); 17 18 /* モジュールをimport */ 19 set_path(); 20 pModule = PyImport_ImportModule("c"); 21 22 /* pythonで言う pTmp = getattr(pModule, 'func')() みたいな。 */ 23 pTmp = PyObject_CallMethod(pModule, "func", NULL); 24 25 /* PyObjectをC言語の型に変換 */ 26 PyArg_Parse(pTmp, "s", &sTmp); 27 printf("%s\n", sTmp); 28 29 Py_Finalize(); 30 31 return 0; 32} 33

普通 python3 ... と呼び出したときはカレントディレクトリのファイルでもインポートできるようなので、どういった事情でカレントディレクトリが省かれているのかは分かりません。ただ、カレントディレクトリをパスに追加するというのは往々にしてセキュリティ上の問題があることも多いので、多用しないほうが良さそうです。

投稿2018/09/15 01:34

編集2018/09/21 12:58
Eki

総合スコア429

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

uriuri

2018/09/19 08:44

返答遅れてすみません 回答を参考にコードを書き換えました ---c #include <stdio.h> #include <Python.h> void set_path(void){ PyObject *sys = PyImport_ImportModule("sys"); PyObject *sys_path = PyObject_GetAttrString(sys, "path"); PyObject *dir = PyUnicode_FromString("."); PyList_Append(sys_path, dir); } int main(void) { PyObject *pModule, *pTmp; char *sTmp; Py_Initialize(); /* モジュールをimport */ pModule = PyImport_ImportModule("c.py"); /* pythonで言う pTmp = getattr(pModule, 'func')() みたいな。 */ pTmp = PyObject_CallMethod(pModule, "func", NULL); /* PyObjectをC言語の型に変換 */ PyArg_Parse(pTmp, "s", &sTmp); printf("%s\n", sTmp); Py_Finalize(); return 0; } --- gcc -fPIC python_c.c $(python3-config --cflags --ldflags) を行いa.outを実行した結果 質問した結果と同じになってしまいました c.pyとpython_c.cはホームにあります PyObject *dir = PyUnicode_FromString("."); の説明どおり現在いるディレクトリから実行しているのであっているとおもうのですが アドバイスいただけると助かります
Eki

2018/09/19 14:32

PyImport_ImportModule("c.py") の "c.py" を、拡張子を除いて単に "c" とすればどうでしょうか? あ、カレントディレクトリにある c.py の名前は変更しないでそのままにしておいてください。
uriuri

2018/09/21 03:05

拡張子を単にcにしてみても変わらずでした. 名前も変更せずにおいてあるのですが... Ekiさんは上記のコードと同じですか?
Eki

2018/09/21 13:07

最初は要点だけ見えた方が分かりやすいかと思い、変化ない部分を省略したのですが、回答を編集してソースコードを全文掲載しました。実際にコンパイル・実行して問題ないことを確認したものをコピー&ペーストしたものです。 「拡張子を単にcにしてみても」という文が「拡張子を除いて単にcにしてみても」の誤記ならよいのですが、おっしゃるように拡張子を c に変更して PyImport_ImportModule("c.c") のようにされたのなら失敗するのも納得できます。 どうしてもうまくいかない場合、 pModule = PyImport_ImportModule("c"); if (!pModule) { PyErr_Print(); return 1; } のようにエラーチェックを挟んでみてはどうでしょうか。失敗してもエラーメッセージを表示してくれますので便利です。
Eki

2018/09/21 13:12

あ。コメントのコードをもう一度丁寧に拝見したところ、定義した set_path() を呼びだしていないようです。 PyImport_ImportModule("c") の前で set_path(); を呼び出してください。 見落していました。
uriuri

2018/09/25 08:34

ごめんなさい 自分の見落としでお手数おかけしました 解決しました ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問