Python C APIを使用してエラーが表示されないという問題が発生しています。Python C API:いくつかのPyObjectを作成した後のWindowsError
背景:私はしばらくの間、ネイティブコード(C++)を実行するためにを使用してきたが、今まで、私は実際にPythonのC APIを使用して、特定の何をやったことがなかったです。私は主にPythonから構造体を渡し、C++から構造体を埋めていました。私が構造体を使用していた方法は面倒になってきたので、私はPythonオブジェクトをC++で直接作成し、Pythonスクリプトに渡してみることに決めました。
コード: 私は一つだけの機能でDLL(Foo.dll
)を持っている:
#define N 223
__declspec(dllexport) void Bar(void)
{
std::cout << "Bar" << std::endl;
for (int i = 0; i < N; ++i)
{
auto list = PyList_New(0);
std::cout << "Created: " << i << std::endl;
//Py_DECREF(list);
}
}
そして私は私が実行しているPythonスクリプトがあります:何が起こる
import ctypes as C
dll = r"C:\path\to\dll\Foo.dll"
Foo = C.CDLL(dll)
# lists = [[] for _ in range(0)]
Foo.Bar()
print "Done."
を:上記のDLLのN
を222
以下と定義すると、コードは正常に動作します(ただし、メモリリークは例外ですが、問題ではない)。
//Py_DECREF(list)
行のコメントを外すと、コードは正常に動作します。
ただし、上記のコードで、私はこの取得:実際には
Bar
Created: 0
Created: 1
Created: 2
...(omitted for your sake)
Created: 219
Created: 220
Created: 221
Traceback (most recent call last):
File "C:\path_to_script\script.py", line 9, in <module>
Foo.Bar()
WindowsError: exception: access violation reading 0x00000028
を、私は上の辞書、リスト、タプルとし、これと同じ結果を得ます。リストを作成して空のサブリストをそのリストに追加すると、同じ結果が得られます。
私は実際のPythonスクリプト内から作成するすべてのリストは、DLLがこのウィンドウエラーを取得する前に行うことができるリストの数を減らします。
私はPythonスクリプトで222以上のリストを作成すると、さらに悪いことに、DLLは720 のようなものが作成されるまでこのエラーに遭遇しません。
**その他の詳細:**
- Anaconda2 32ビットのPython 2.7配布その分布
- python.exeから
Python.h
とpython27.lib
を使用 - を(使用してWindows 10 - バージョン:
2.7.13 :: Anaconda custom (32-bit)
- Visual StudioでDLLを作成する2017
C++コードから多くのPyObject
を作成しない限り、すべて正常に動作しているようです。私はPyObject
をPythonコードとの間でやりとりすることができます。そして、私のC++コード内からオブジェクトが "あまりにも多く"作成されるまでは正常に動作します。
何が起こっているのですか?
私は両方のソリューションは、pを解決するために表示されていることを確認しました汚れ。彼らは私が実際にドキュメンテーション_を読んでくれることをどうにかしていますか?ありがとう。 – Aaron
私は、「Python C APIで単純なことをやっているときのミステリーエラーは、通常GILによるものかPythonの初期化ではない」という考えから作業を始めました。次に、GILのctypesドキュメントを検索しました。私は実際には詳細な文書も読んでいませんでした。 – DavidW