Я хочу вызвать функцию 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>
Как заставить это работать?
Это не имеет ничего общего с 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). Когда компилятор выдает предупреждение, это часто является ответом на вопрос «почему мой код делает неправильные вещи, даже если он компилируется».
Несколько других вещей не так с вашим кодом:
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
вызов становится встроенным — но на самом деле детали не имеют значения; код не должен работать, и это не так, так кого это волнует, почему?
Других решений пока нет …