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

Binding Python/C++ template with SWIG

本文关键字:C++ 模板 Python SWIG 绑定 使用      更新时间:2023-10-16

我尝试用SWIG绑定Python中的C++模板。 我希望我的字体名 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

我的人格.cpp只包含: #include "人物.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,所以你返回的浮点数将转换为 double,而附加数字将只是未初始化的内存,但是当你打印值时,这些也会被考虑在内。

你甚至不需要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