如何编写一个函数来接受 SWIG 中的 Fraction 对象?
How can I write a function to accept a Fraction object in SWIG?
我正在使用 SWIG 在 Python 和我们的 C++ 视频处理库之间编写接口。在 python 中,我使用 Fraction
class 来表示帧速率(例如 NTFS24 = 24000/1001 FPS)。所讨论的功能是视频转码,即获取视频(或帧流)输入并产生类似的输出。为此,我们需要指定输出(有时是输入)帧速率。
有什么方法可以在 C++ (SWIG) 端连接 Fraction class 吗?根据我在 Internet 上找到的内容,我应该能够将 tuple
传递给 std::pair<int,int>
参数,所以这是我的后备计划,但有没有更好的方法?谢谢!
我整理了以下接口文件来说明包装 Fraction 的工作原理。最后我决定创建我自己的分数结构来保存 C++ 端的分数,主要是因为它比使用 std::pair<int, int>
更明确。 (我认为一对整数也可以是 2D 坐标、屏幕分辨率或许多其他类型,更强的类型对于重载分辨率等来说是更好的选择)
%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);
= &tmp;
}
%typemap(out) Fraction {
// Output typemap: pass two ints into fractions.Fraction() ctor
$result = PyObject_CallMethod(fractions_module, "Fraction", "ii", .numerator, .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++ 分数,并分别从我们的 C++ 对象构造一个 fractions.Fraction
Python 对象。将它们改编为其他类似的小数类型应该相当简单。
我正在使用 SWIG 在 Python 和我们的 C++ 视频处理库之间编写接口。在 python 中,我使用 Fraction
class 来表示帧速率(例如 NTFS24 = 24000/1001 FPS)。所讨论的功能是视频转码,即获取视频(或帧流)输入并产生类似的输出。为此,我们需要指定输出(有时是输入)帧速率。
有什么方法可以在 C++ (SWIG) 端连接 Fraction class 吗?根据我在 Internet 上找到的内容,我应该能够将 tuple
传递给 std::pair<int,int>
参数,所以这是我的后备计划,但有没有更好的方法?谢谢!
我整理了以下接口文件来说明包装 Fraction 的工作原理。最后我决定创建我自己的分数结构来保存 C++ 端的分数,主要是因为它比使用 std::pair<int, int>
更明确。 (我认为一对整数也可以是 2D 坐标、屏幕分辨率或许多其他类型,更强的类型对于重载分辨率等来说是更好的选择)
%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);
= &tmp;
}
%typemap(out) Fraction {
// Output typemap: pass two ints into fractions.Fraction() ctor
$result = PyObject_CallMethod(fractions_module, "Fraction", "ii", .numerator, .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++ 分数,并分别从我们的 C++ 对象构造一个 fractions.Fraction
Python 对象。将它们改编为其他类似的小数类型应该相当简单。