2

私は、この拡張 C モジュールがリモート プロシージャ コール (RPC) を作成してネットワーク サービスにアクセスする Python の C 拡張に取り組んでいます。この C モジュールは、RPC の結果 (収集された情報) にメソッド Py_BuildValue を適用し、それを PyList_Append メソッドを使用してリストに追加します。最後に、このリスト オブジェクトは呼び出し元の Python スクリプトに戻ります。この C モジュールを共有 .so ファイルの形式に変換して、Python で使用できるようにします。

メモリ リークの問題を解決するために、RPC の結果の Py_BuildValue をリストに直接追加する代わりに、この Py_BuildValue の結果を PyObject 変数に割り当て、その変数をリストに追加するようにコードを修正しました。変数をリストに追加した後、Py_DECREF を使用してこの PyObject 変数の参照カウントを減らします。この変更の後、あるマシンで Python スクリプトを実行すると、次のエラーが発生しました。

ImportError: /usr/local/support/iadrpcmodule.so: 未定義のシンボル: Py_InitModule4

しかし、私は Py_InitModule3 のみを使用している C モジュールで変数 'Py_InitModule4' を使用していません。

Python 2.4 を使用してコードをコンパイルし、64 ビットの Linux マシンで実行しました。

ここでも興味深いのは、マシンを再起動したときに問題が消えたことです..!!。
別のマシンで試したとき、この問題は発生しませんでした。

PEP0353 (http://www.python.org/dev/peps/pep-0353/) に従って、Python 2.5 の場合は 64 ビット マシンの名前が変更され、32 を想定する拡張モジュールのロードを防ぐことがわかりました。 -ビットサイズの型を 64 ビットサイズの型を持つインタープリターに変換すると、Py_InitModule4 は Py_InitModule4_64 に名前が変更されます。

このような問題が発生する理由と、マシンの再起動時に解決する方法を教えてください。これは、メモリ リークの問題を修正するためにコードを変更したためであり、この「インポート エラー」を解決するためにコードを変更する必要がありますか? コードで Py_InitModule4 を使用していないため、名前を Py_InitModule4_64 に変更して 64 ビット マシンで動作させるにはどうすればよいですか?

いくつかの修正を適用した以前のコードは、次のようなものです

PyList_Append(outlist,      
              Py_BuildValue(
                    "ss#" "iiiiiiiii" "iiiii" "iiiiiiiiiiiiiiiii" "IIIIIIII",   
                     name,                
                     ref_counter,           
                     type,      
                     local,     
                     proto,                    
                     state)                      
                );    
return Py_BuildValue("O", outlist);

メモリリークの問題を解決するために、次のようにコードを変更しました。

PyObject *hostResult = Py_BuildValue(
                    "ss#" "iiiiiiiii" "iiiii" "iiiiiiiiiiiiiiiii" "IIIIIIII",                    
                    name,                    
                    ref_counter,  
                    type,  
                    local,                      
                    proto,   
                    state);                    
PyList_Append(outlist,
              hostResult);   
Py_DECREF(hostResult);   
PyObject * arglist = Py_BuildValue("O", outlist);    
Py_DECREF(outlist);    
return arglist;

また、モジュールを初期化するための別の関数は、Py_InitModule3 を使用している次のとおりです。

PyMODINIT_FUNC initdrpc(void)
{
    PyObject * m;

    drpc_ClientType.tp_new = PyType_GenericNew;    
    drpc_ClientType.tp_dealloc = (destructor)Client_dealloc;
    if (PyType_Ready(&drpc_ClientType) < 0) {
        return;
    }

    m = Py_InitModule3("drpc", dRpcMethods, module_doc);
    }
};

このコードは Python 2.4 を使用してコンパイルされており、任意の 64 ビット マシンで実行されます。実行マシンには、Python 2.4 と Python 2.5 の両方が含まれている場合があります。

私の質問は、拡張モジュールを Python 2.5 にロードしないようにするために、このモジュールで「Py_InitModule4」を明示的に定義して名前を変更する必要がありますか? 以下のようなもの

#if SIZEOF_**strong text**SIZE_T != SIZEOF_INT
/* On a 64-bit system, rename the Py_InitModule4 so that 2.4
   modules cannot get loaded into a 2.5 interpreter */
#define Py_InitModule4 Py_InitModule4_64
#endif
4

0 に答える 0