Обязательный шаблон Python / C ++ с SWIG - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь связать шаблон C ++ в Python с помощью 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».

Когда я набираю «FpersSimple» на Python, я получаю:

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

Так что мой FpersSimple содержит определенно число с плавающей точкой.

Я не понимаю, где я мог испортить.

Спасибо за ваше время!

Спасибо за ваше время и ваши ответы!

1 Ответ

0 голосов
/ 09 июля 2018

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
...