implicit declaration of function 'PyString_AS_STRING' is invalid

206 views
Skip to first unread message

Noon Chen

unread,
Apr 25, 2021, 6:32:39 AM4/25/21
to cython-users
Hi,

I ran into this error when I was trying to build my code, and here is the example code that can reproduce it (python 3.8 + cython 3.0a6):

```
# distutils: language = c
# cython: language_level=3

from cpython.string cimport PyString_AS_STRING

cdef void test(char* name):
    pass

test(PyString_AS_STRING(f'testString'))
```
Error:
```
test.c:1898:22: error: implicit declaration of function 'PyString_AS_STRING' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
  __pyx_f_4test_test(PyString_AS_STRING(__pyx_n_u_testString));
                     ^
test.c:1898:22: warning: incompatible integer to pointer conversion passing 'int' to parameter of type 'char *' [-Wint-conversion]
  __pyx_f_4test_test(PyString_AS_STRING(__pyx_n_u_testString));
                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.c:1468:52: note: passing argument to parameter '__pyx_v_name' here
static void __pyx_f_4test_test(CYTHON_UNUSED char *__pyx_v_name) {
                                                   ^
1 warning and 1 error generated.
error: command 'clang' failed with exit status 1
```

I did search for this error in the group and google, it should be related to the import issue, but I found the `PyString_AS_STRING` in `include/cpython/string.pxd`, what did I do wrong here?

Stefan Behnel

unread,
Apr 25, 2021, 6:33:54 AM4/25/21
to cython...@googlegroups.com
You are trying to use a Py2 function in Py3.

Stefan Behnel

unread,
Apr 25, 2021, 6:36:35 AM4/25/21
to cython...@googlegroups.com
Read the documentation page on strings. You may need to encode your Unicode string. Or you may have to do something entirely different, depending on what your actual problem is.

Noon Chen

unread,
Apr 25, 2021, 1:12:26 PM4/25/21
to cython-users
Seems that I can rewrite the code as follow:
```
cdef void test(char* name):
    pass

test(f'testString'.encode("utf-8"))
```
And cython would convert the code to:
```
#define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s))

__pyx_t_2 = __Pyx_PyBytes_AsWritableString(__pyx_n_b_testString); if (unlikely((!__pyx_t_2) && PyErr_Occurred())) __PYX_ERR(0, 205, __pyx_L1_error)
__pyx_f_4test_test(__pyx_t_2);
```
Is the performance comparable to the 1st approach?

Thanks in advance!

Noon Chen

unread,
Apr 25, 2021, 1:12:38 PM4/25/21
to cython-users
Hi Stefan,

Thanks for your reply, I didn't see any version info in cpython/string.pxd. 

I'm simply want to convert python strings to char*, I used to do this:
```
cdef str py_string = "xxxxx"
cdef bytes py_byte = py_string.encode("utf-8")
cdef char* cstring = py_byte
```
However, it was quite cumbersome, and I found `PyString_AS_STRING` in cython built-in package that perfectly fits my needs.

Does it mean I can only use the 1st option? Is there any py3 alternative of `PyString_AS_STRING`?

Best Regards,
NC
On Sunday, April 25, 2021 at 6:36:35 PM UTC+8 Stefan Behnel wrote:

Stefan Behnel

unread,
Apr 25, 2021, 2:11:47 PM4/25/21
to cython...@googlegroups.com
Am 25. April 2021 15:23:25 MESZ schrieb Noon Chen:
>Seems that I can rewrite the code as follow:
>
>cdef void test(char* name):
> pass
>
>test(f'testString'.encode("utf-8"))

Note that you are not testing a real world situation here. Cython can see that the result of the encoding is a constant bytes object and uses that instead.

Read the Cython documentation on string encoding. It explains what you have to do and why some things don't work.

Stefan

Reply all
Reply to author
Forward
0 new messages