Я собрал следующий файл интерфейса, чтобы проиллюстрировать, как может работать упаковка Fraction. В конце концов я решил создать свою собственную структуру фракций для хранения фракций на стороне C ++, в первую очередь потому, что она менее двусмысленна, чем использование std::pair<int, int>
. (Я полагал, что пара целых чисел также может быть двухмерной координатой, или разрешением экрана, или многими другими типами, и более строгая типизация лучше для разрешения перегрузки и т. Д.)
%module test
%{
#include <iostream> // Just for testing....
static PyObject *fractions_module = NULL;
%}
%init %{
// Import the module we want
fractions_module = PyImport_ImportModule("fractions");
assert(fractions_module);
// TODO: we should call Py_DECREF(fractions_module) when our module gets unloaded
%}
%typemap(in) const Fraction& (Fraction tmp) {
// Input typemap for fraction: duck-type on attrs numerator, denominator
PyObject *numerator = PyObject_GetAttrString($input, "numerator");
PyObject *denominator = PyObject_GetAttrString($input, "denominator");
int err = SWIG_AsVal_int(numerator, &tmp.numerator);
assert(SWIG_IsOK(err)); // TODO: proper error handling
err = SWIG_AsVal_int(denominator, &tmp.denominator);
assert(SWIG_IsOK(err)); // TODO: errors...
Py_DECREF(numerator);
Py_DECREF(denominator);
$1 = &tmp;
}
%typemap(out) Fraction {
// Output typemap: pass two ints into fractions.Fraction() ctor
$result = PyObject_CallMethod(fractions_module, "Fraction", "ii", $1.numerator, $1.denominator);
}
%inline %{
struct Fraction {
int numerator, denominator;
};
void fraction_in(const Fraction& fraction) {
std::cout << fraction.numerator << "/" << fraction.denominator << "\n";
}
Fraction fraction_out() {
Fraction f = {100, 1};
return f;
}
%}
В основном это всего двакарты типов - один для входов в функции C ++ и один для выходов. Они создают временную фракцию C ++ из атрибутов числителя и знаменателя входного объекта и соответственно создают объект fractions.Fraction
Python из нашего объекта C ++. Адаптировать их для других подобных дробных типов должно быть довольно просто.