2

先週同様の質問を投稿しましたが、多くの回答が得られなかったので、より良い説明で再度投稿しようと思います。

ubuntu 11.04でdjango Webアプリを実行しており、cython/pyrexを使用してサードパーティのC APIを呼び出しています。

Python から C API を呼び出せるようにするために必要なすべてのファイルをコンパイルした後、スタンドアロンの Python スクリプトを実行して動作を確認することにしました。少しテストした後、正しく実行することができました。Pythonから呼び出すことで、C APIから必要な情報を印刷して取得できます。

C api を呼び出すために Python と共に使用されている Cython/Pyrex コードを次に示します。

get_params.pyx:

cimport cste
ctypedef signed int int32_t
ctypedef signed int int16_t


cdef class CEngineApi:

cdef cste.ste_handle* _ste_handle

def __cinit__(self, path):
    self._ste_handle = cste.ste_init(path)

def __dealloc__(self):
    pass

def ste_get_all_params(self):
    cdef char stateC[3]
    cdef char countyC[4]
    cdef char cityC[7]
    call_ok = cste.ste_get_all_params(self._ste_handle, stateC, countyC, cityC)
    return stateC, countyC, cityC

cste.pxd:

from libc.stddef cimport wchar_t, size_t
ctypedef unsigned short uint16_t
ctypedef signed int int32_t
ctypedef signed int int16_t

cdef extern from "ste.h":

    ctypedef struct ste_handle:
        pass

    ste_handle* ste_init(const char *path)

    uint16_t ste_get_all_params (const ste_handle * ste,  
                                 char * stateCode, 
                                 char * countyCode, 
                                 char * cityCode)

これは、API get_param_test.py への呼び出しを行った後に正しいパラメーターを返すスタンドアロンの python スクリプトです。

from cenginelib import CEngineApi
import os

PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
CENGINE_LIBARY_PATH=os.path.join(PROJECT_PATH, 'ste-root' )

engine = CEngineApi(CENGINE_LIBARY_PATH)

state_code, county_code, city_code = engine.ste_get_all_params()
print "State code : %s" % (state_code)

注: C API のコードをコンパイルすると、cenginelib.so が作成されるため、そこから CEngineApi をインポートしています。

ただし、上記のpythonスクリプトを実行すると、私が言ったように正しく実行され、吐き出されます:「状態コード:36」

最初は3つの数字すべてを出力しようとしましたが、デバッグ上の理由から、djangoアプリ内で実行時に返されるこの1つの数字を取得しようとしています.

ここで、C API を呼び出す私の django アプリ内で使用されるコードはほとんど同じですが、混乱を避けるために追加します。

settings.py は、API をインスタンス化する場所です。

from cenginelib import CEngineApi
import os

PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))
CENGINE_LIBARY_PATH=os.path.join(PROJECT_PATH, 'ste-root' )

CAPI_engine = CEngineApi(CENGINE_LIBARY_PATH)
.....

これは、APIを呼び出すモデルのメソッドです:

from django.conf import settings
def ste_get_all_params_method(self):
    stC, countyC, cityC = settings.CAPI_engine.ste_get_all_params()
    return stC

最後に、これが私のテンプレートで、このモデル メソッドを呼び出して、フロント エンドの param_template.html で API 出力を表示するようにします。

<ul>
      <li>
          {{pay_model.ste_get_all_params_method}}
      </li>
</ul>

django から返されるエラーは DjangoUnicodeDecodeError です。

Exception Value: 'utf8' codec can't decode byte 0x9c in position 2: invalid start byte. You passed in '\xc5\x99\x9c\x01' (<type 'str'>)

注: エラーはサーバーから私のメールに送信されたため、エラーの形式が若干異なる場合があります。

これを修正するために、django.utils.encodingからencode()、decode()を使用するなど、考えられるすべてのことを試しました。これを修正する方法、または正しい方向に向ける方法を教えていただければ幸いです。オンラインで見つけられるものはすべて読みましたが、まだ解決策がありません。助けてください。ありがとう。

4

0 に答える 0