Как передать строку из Python3 в функцию C ++

Я пытаюсь понять, как передавать строковые значения между Python3 и функции C ++. Однако я не могу собрать библиотеку с помощью Cython.

В частности, я не понял, как объявить возвращаемое значение строки и строковый параметр в source.pyx, С типом int он работает правильно.

Ошибка, которую я получаю при сборке с помощью clang, заключается в следующем:

candidate function not viable: no known conversion from 'PyObject *' (aka '_object *') to 'char *' for 1st argument

мой source.pyx является следующим:

cdef extern from "source.cpp":
cdef str fun(str param)

def pyfun(mystring):
return fun(mystring)

мой source.cpp является:

char * fun(char *string) {
return string;
}

0

Решение

Помимо ошибок в исходном коде, мне удалось заставить его работать со следующими source.pyx (перевод между bytes введите Python3 и char* в C ++):

cdef extern from "source.cpp":
cdef char* fun(char* param)

def pyfun(mystring):
mystring_b = mystring.encode('utf-8')
rvalue = fun(mystring_b).decode('utf-8')
return rvalue

Если память выделена с помощью malloc в fun он также должен быть освобожден, иначе произойдет утечка памяти (при работе с указателями Си всегда стоит подумать, кому принадлежит память). Модифицированная версия, которая делает это:

from libc.stdlib cimport free

# cdef extern as before

def pyfun(mystring):
cdef char* value_from_fun
mystring_b = mystring.encode('utf-8')
value_from_fun = fun(mystring_b)
try:
return value_from_fun.decode('utf-8')
finally:
free(value_from_fun)

Преобразования типов действуют так же, как и раньше.


редактировать

Согласно hpauljкомментарий в оригинальном вопросе, вот версия с libcpp.string какие карты C ++ std::string определяется в <string>:

from libcpp.string cimport string

cdef extern from "source.cpp":
cdef string fun(string param)

def pyfun(mystring):
mystring_ = mystring.encode('utf-8')
rvalue = fun(mystring_).decode('utf-8')
return rvalue
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector