使用 SWIG 绑定 Python/C++ 模板

Posted

技术标签:

【中文标题】使用 SWIG 绑定 Python/C++ 模板【英文标题】:Binding Python/C++ template with SWIG 【发布时间】:2018-06-05 08:37:49 【问题描述】:

我尝试将 Python 中的 C++ 模板与 SWIG 绑定。 我希望我的类型名 T 可以是浮点数或双精度数。 我使用 SWIG 3.0.8

这是我的 C++ 模板:Personnage.hpp(不要全部阅读,我们只对 1 个函数感兴趣)

#ifndef PERSONNAGE_H_INCLUDED
#define PERSONNAGE_H_INCLUDED

#include <string>
#include <iostream>
#include <sstream>

template <typename T> 
class Personnage

    public:

        Personnage();

        ~Personnage();

        void setAge(const int &age);

        void setTaille(const T &taille);

        int getAge() const;

        T getTaille() const;


    protected:
        std::string P_nom;

        int P_age;

        T P_taille;
;

template<typename T>
Personnage<T>::Personnage()
: P_nom("Rigoberto"), P_age(42), P_taille(T(1.10))



template<typename T>
Personnage<T>::~Personnage()

template<typename T>
void Personnage<T>::setAge(const int &age)

    P_age = age;


template<typename T>
void Personnage<T>::setTaille(const T &taille)

    P_taille = taille;


template<typename T>
int Personnage<T>::getAge() const

    return P_age;


template<typename T>
T Personnage<T>::getTaille() const

    return P_taille;




#endif // PERSONNAGE_H_INCLUDED

我的 Personnage.cpp 只包含: #include "Personnage.hpp"

这是我的接口文件:Personnage.i

%module Personnage

%
#include "Personnage.hpp"
%




%include "Personnage.hpp"

%module Personnage

%
#include "Personnage.hpp"
%

%rename (PersonnageD) Personnage::Personnage();
%rename (PersonnageC) Personnage::Personnage(const Personnage<T> &personnage);


%include "Personnage.hpp"
%include "std_string.i"

//constructeurs simples

%template(PFloat) Personnage<float>;
%template(PDouble) Personnage<double>;

%template(estGrand) estGrand<float, float>;
%template(estGrand) estGrand<float, double>;
%template(estGrand) estGrand<double, float>;
%template(estGrand) estGrand<double, double>;

我使用这些行来使用 SWIG 并编译:

swig -c++ -python Personnage.i
g++ -fPIC -c Personnage.cpp
g++ -fPIC -c Personnage_wrap.cxx $(python-config --cflags)
g++ -shared Personnage.o Personnage_wrap.o $(python-config --ldflags) -o _Personnage.so

这是我用来测试的python文件:

import Personnage
persSimple = Personnage.PDouble("didier",45,1.59) #Player with a "Taille" in Double
print(persSimple.getTaille())
FpersSimple = Personnage.PFloat("didier",45,1.59) #Player with a "Taille" in Float
print(FpersSimple.getTaille())

第一个打印显示“1.59”,它是正确的。 第二个打印显示“1.5900000(随机数)”,这正是我在这里寻求帮助的原因:它应该只显示“1.59”。

当我在 Python 上输入“FpersSimple”时,我得到:

<Personnage.PFloat; proxy of <Swig Object of type 'Personnage< float > *' at 0x7fd2742b3480> >

所以我的 FpersSimple 肯定包含一个浮点数。

我不明白我在哪里搞砸了。

感谢您的宝贵时间!

感谢您的宝贵时间和回答!

【问题讨论】:

Python只知道double,所以你返回的float会被转换成double,额外的数字只是未初始化的内存,但是当你打印值时,这些也会被考虑在内。 你好@HenriMenke!我就是这么想的,谢谢你的回答! 【参考方案1】:

Python 只知道双精度,所以你返回的浮点数会被转换成双精度,而额外的数字只是未初始化的内存,但是当你打印值时,这些也会被考虑在内。

您甚至不需要使用 SWIG 和 Python 的复杂示例来重现这一点。只需从一个双精度浮点数初始化一个浮点数(文字 1.59 是一个双精度浮点数)并以双精度打印它。

#include <iomanip>
#include <iostream>
#include <limits>

int main() 
    double d = 1.59;
    float f = 1.59;
    std::cout << std::setprecision(std::numeric_limits<double>::digits10)
              << std::fixed
              << d << '\n'
              << f << '\n';

1.590000000000000
1.590000033378601

【讨论】:

以上是关于使用 SWIG 绑定 Python/C++ 模板的主要内容,如果未能解决你的问题,请参考以下文章

SWIG C++/Python 绑定和支持带有 std::enable_if 的条件成员

使用 SWIG 从 Python 向 C 传递和数组参数

我们可以使用 SWIG 为 Qt 应用程序制作 python 绑定吗?

Ruby 和 SWIG 与 CMake

swig模板引擎汇总

wxlua 绑定不适用于我使用 SWIG 制作的着色器对象