我上周发布了一个与此类似的问题,但没有得到很多回复,所以我会尝试再次发布它并提供更好的解释。
我在 ubuntu 11.04 上运行 django web 应用程序并使用 cython/pyrex 调用第三方 C api。
在编译所有必要的文件以便能够从 python 调用 C api 之后,我决定运行一个独立的 python 脚本以确保它工作。经过一些测试,我能够让它正确运行。我可以通过从 python 调用 C api 来打印和检索必要的信息。
这是与 python 一起用于调用 C api 的 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)
这是我的独立 python 脚本,它在调用 api get_param_test.py 后返回正确的参数:
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”
我最初尝试打印出所有三个数字,但出于调试原因,我只是试图在运行时在我的 django 应用程序中返回这个单个数字。
现在,我调用 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
最后,这是我的模板,我在其中调用此模型方法,以尝试让它在前端显示 api 输出 param_template.html:
<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() 以及其他许多东西。如果你能给我一个关于如何解决这个问题的想法或指出我正确的方向,我将不胜感激。我已经阅读了我可以在网上找到的所有内容,但仍然没有解决方案。请帮忙。谢谢。