私は、引数としてstr
オブジェクトを受け入れるはずのC拡張関数を作成していました。python3 strオブジェクトはPyUnicode_Checkを渡すことができません
static PyObject *py_print_chars(PyObject *self, PyObject *o) {
PyObject *bytes;
char *s;
if (!PyUnicode_Check(o)) {
PyErr_SetString(PyExc_TypeError, "Expected string");
return NULL;
}
bytes = PyUnicode_AsUTF8String(o);
s = PyBytes_AsString(bytes);
print_chars(s);
Py_DECREF(bytes);
Py_RETURN_NONE;
}
しかし、私はのpython3コンソールでモジュールをテストとして、私はstr
オブジェクトがPyUnicode_Check
を渡すことはできません見つける:コードを以下に示します
>>> from sample2 import *
>>> print_chars('Hello world')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Expected string
、Pythonの3のstr()
typeはCでPyUnicodeと呼ばれ、上記のCコードは "python cookbook3" Char15.13を参照して書かれています。私は問題を解決できません。誰でも私のコードに何が間違っているのか教えてもらえますか?
何らかの理由で、あなたはPyObject *と直接作業しているとはPyArg_ParseTuple()を使用することができない場合は、次のコードサンプルは、あなたがチェックして抽出する方法を示しています。ここでは
は言った、「パイソンcookbook3」でありますバイト、文字列オブジェクトの両方から適当char *
参照:
/* Some Python Object (obtained somehow) */
PyObject *obj;
/* Conversion from bytes */
{
char *s;
s = PyBytes_AsString(o);
if (!s) {
return NULL; /* TypeError already raised */
}
print_chars(s);
}
/* Conversion to UTF-8 bytes from a string */
{
PyObject *bytes;
char *s;
if (!PyUnicode_Check(obj)) {
PyErr_SetString(PyExc_TypeError, "Expected string");
return NULL;
}
bytes = PyUnicode_AsUTF8String(obj);
s = PyBytes_AsString(bytes);
print_chars(s);
Py_DECREF(bytes);
}
全体コード:
#include "Python.h"
#include "sample.h"
static PyObject *py_print_chars(PyObject *self, PyObject *o) {
PyObject *bytes;
char *s;
if (!PyUnicode_Check(o)) {
PyErr_SetString(PyExc_TypeError, "Expected string");
return NULL;
}
bytes = PyUnicode_AsUTF8String(o);
s = PyBytes_AsString(bytes);
print_chars(s);
Py_DECREF(bytes);
Py_RETURN_NONE;
}
/* Module method table */
static PyMethodDef SampleMethods[] = {
{"print_chars", py_print_chars, METH_VARARGS, "print character"},
{ NULL, NULL, 0, NULL}
};
/* Module structure */
static struct PyModuleDef samplemodule = {
PyModuleDef_HEAD_INIT,
"sample",
"A sample module",
-1,
SampleMethods
};
/* Module initialization function */
PyMODINIT_FUNC
PyInit_sample2(void) {
return PyModule_Create(&samplemodule);
}
'' PyArg_ParseTuple'に 'u'の引数を先に入れる必要はありませんか?しかし、METH_VARARGSのようなメソッドテーブルの引数の型に依存します。 – cdarke
はい、事実上、PyArg_parseTupelはこの問題を完全にスローすることができます。しかし、 "python cookbook3"には、PyArg_ParseTupleを使わずに別のワークアウトがあると言われています。 – sun
私は、コードの他の部分が、他のファンクションでうまく機能しているため間違っているかもしれないとは考えていませんでした。質問の説明にコード全体を追加しています。 – sun