ctypes как передать строку из python в функцию c ++ и как вернуть строку из функции c ++ в python

Я хочу вызвать функцию c ++ из python, эта функция c ++ принимает char * в качестве параметра и возвращает строку. Ниже мой код.

wrapper.cpp

#include <Python.h>
#include <string>
#include <iostream>

using namespace std;

extern "C"string return_string(char* name){
cout<<strlen(name)<<endl;
cout<<name<<endl;
string s = "hello ";
s += name;
return s;
}

скомпилируйте wrapper.cpp в example.so

g++ -fPIC wrapper.cpp -o example.so -shared -I/usr/include/python2.7/

wrapper.py

import os
from ctypes import *

lib = cdll.LoadLibrary('./example.so')
lib.return_string.restype = c_char_p
lib.return_string.argtypes = [c_char_p]
name = create_string_buffer("Tom")
s = lib.return_string(name);
print s
print name

вот мой вывод

18
��H�L�l���A���
1
<ctypes.c_char_Array_4 object at 0x7f5f480be710>

Как заставить это работать?

4

Решение

Это не имеет ничего общего с ctypes; Ваш код C ++ сам по себе недействителен. Вы не можете определить extern "C" функция, которая возвращает string,

В быстром тесте с программой на C ++, которая использует ту же библиотеку, она также печатает мусор.

Я также написал программу на C, которая определяет то, что называется string с тем же макетом, что и std::string просто, чтобы я мог скомпилировать его и посмотреть, что произойдет; он также печатает мусор, а затем ~string,

Поэтому неудивительно, что программа Python также печатает мусор.

С небольшим изменением все работает:

extern "C"const char *return_string(char* name){
cout<<strlen(name)<<endl;
cout<<name<<endl;
static string s = "hello ";
s += name;
return s.c_str();
}

Я получаю этот вывод:

3
Tom
hello Tom
<ctypes.c_char_Array_4 object at 0x11011c7a0>

(Или, начиная с версии C ++, то же самое, но с «Tom» в последней строке.)

Конечно, по понятным причинам это не очень хорошее решение, но оно показывает, что возвращение string это проблема.

И g ++ — 4.5, и clang-apple-4.0 предупреждали меня именно об этой проблеме, когда я пытался скомпилировать ваш код C ++ (хотя g ++ — apple-4.2 не сделал, если я не добавил дополнительный флаг -W). Когда компилятор выдает предупреждение, это часто является ответом на вопрос «почему мой код делает неправильные вещи, даже если он компилируется».

Несколько других вещей не так с вашим кодом:

  • Вы не используете ничего из Python в вашем .cpp файле. И вообще, весь смысл использования ctypes ваш код на C или C ++ не должен ничего знать о Python; это ваш код Python, который знает об этом. Таким образом, не включайте или ссылку.
  • Это вообще плохая идея, чтобы взять неконстантный char* если вы не планируете изменять его. Мой драйвер C ++ должен был вызвать его с const_cast<char*>(name.c_str()) вместо просто name.c_str(), Кроме того, это может помешать компилятору замечать другие вещи, которые вы делаете.

Вот драйвер C ++, о котором я упоминал выше:

#include <iostream>
#include <string>
using namespace std;

extern "C" string return_string(char* name);

int main(int argc, char *argv[]) {
string name("Tom");
string s(return_string(const_cast<char *>(name.c_str())));
cout << s << "\n";
cout << name << "\n";
return 0;
}

Кроме того, если я поиграюсь с разными настройками оптимизации или немного реорганизовываю код, в моем драйвере C ++ иногда ваш код действительно работает, иногда он печатает мусор, а иногда и его ошибки. Мое первое предположение было бы, что это зависит от того, где ~string вызов становится встроенным — но на самом деле детали не имеют значения; код не должен работать, и это не так, так кого это волнует, почему?

11

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

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

По вопросам рекламы [email protected]