ctypes не имеет API publi c, который можно использовать из C / C ++ для разработчиков расширений, поэтому обработка ctypes с помощью cppyy по необходимости несколько неудобна. Что не так, так это то, что сгенерированный массив ctypes const char*
имеет тип const char*[2]
, а не const char*[]
, и поскольку cppyy выполняет прямое сопоставление типов для типов ctypes, это не удается.
Как есть, некоторые код где-то должен выполнить преобразование Python строк в C нижнего уровня и удерживать эту память на время вызова. Лично я бы использовал небольшую оболочку C ++, вместо того, чтобы все продумывать на стороне Python. Дело в том, что std::vector<std::string>
может иметь дело с необходимыми преобразованиями (поэтому тип bytes
не нужен, например, но, конечно, разрешен, если вы хотите), и он может хранить временную память.
Итак , если вам предоставлен какой-то сторонний интерфейс, подобный этому (вставив его в строку для cppyy только для примера):
import cppyy
cppyy.cppdef("""
float method(const char* args[], int len) {
for (int i = 0; i < len; ++i)
std::cerr << args[i] << " ";
std::cerr << std::endl;
return 42.f;
}
""")
Тогда я бы создал оболочку:
# write a C++ wrapper to hide C code
cppyy.cppdef("""
namespace MyCppAPI {
float method(const std::vector<std::string>& args) {
std::vector<const char*> v;
v.reserve(args.size());
for (auto& s : args) v.push_back(s.c_str());
return ::method(v.data(), v.size());
}
}
""")
Затем замените исходный C API версией C ++:
# replace C version with C++ one for all Python users
cppyy.gbl.method = cppyy.gbl.MyCppAPI.method
, и все будет так, как ожидалось для любого другого человека ниже по течению:
# now use it as expected
cppyy.gbl.method(["aap", "noot", "mies"])
Все, что сказано, очевидно, что нет причины, по которой cppyy не мог бы выполнить эту часть обертывания автоматически. Я создал эту проблему: https://bitbucket.org/wlav/cppyy/issues/235/automatically-convert-python-tuple-of