Проблема несоответствия сигнатур Boost Python

#c #python #boost-python

#c #python #boost-python

Вопрос:

Я получаю несоответствие сигнатур с методом, который я предоставляю python. Вот приведенный ниже код

 class StatusEffect
{
public:
   //Virtual functions and non related ommitted
   void AddCancellation(std::string amp;effect)
   {
       CancelsEffects.insert(effect);
   }
}
  

В StatusEffect есть несколько виртуальных методов, которые я хочу переопределить в своих скриптах на python, поэтому я создал оболочку класса. Оболочка никоим образом не переопределяет и не изменяет AddCancellation, я просто показываю это марку

 struct StatusEffectWrapper : Game::StatusEffects::StatusEffect
{
   //Wrappings for virtual functions here. I don't touch AddCancellation
}
  

Я предоставляю его Python следующим образом:

  class_<StatusEffects::StatusEffect, boost::noncopyable, std::auto_ptr<StatusEffectWrapper> >("StatusEffect")
    .def("AddCancellation", amp;StatusEffect::AddCancellation)
    ;
  

В моем файле python я расширяю базовый класс StatusEffect следующим образом:

 class StatCreepEffect(StatusEffect):
    def __init__(self, name, stat_, rate_, descript, uid, turns, prior, canrefresh, poseffect, cats, conds, flgs, sep, pers, cancels):
        StatusEffect.__init__(self, name, descript, uid, turns, prior, canrefresh, poseffect, cats, conds, flgs, sep, pers)
        self.rate = rate_
        self.stat = stat_
        self.PushCancellations(cancels)
    def PushCancellations(self, cancels):
        for cancel in cancels:
            print (cancel)
            self.AddCancellation(cancel)

Regen = StatCreepEffect("Regen", Stat.HP, 0.05, "Regenerates a small amount of HP every turn", PrimaryEngine.GetUID(), 14, 4, True, True, StatusCategories.SC_Regen, 0, StatusFlags.TickEffect, True, StatusPersistence.SP_Timer_Cure, ["Poison", "Poison-"])
  

Однако, когда я это делаю, я получаю следующую ошибку:

 Poison
Traceback (most recent call last):
  File "......ResourcesScriptsStatusEffects.py", line 27, in <module>
    Regen = StatCreepEffect("Regen", Stat.HP, 0.05, "Regenerates a small amount
of HP every turn", PrimaryEngine.GetUID(), 14, 4, True, True, StatusCategories.S
C_Regen, 0, StatusFlags.TickEffect, True, StatusPersistence.SP_Timer_Cure, ["Poi
son", "Poison-"])
  File "......ResourcesScriptsStatusEffects.py", line 11, in __init__
    self.PushCancellations(cancels)
  File "......ResourcesScriptsStatusEffects.py", line 23, in PushCancellati
ons
    self.AddCancellation(cancel)
Boost.Python.ArgumentError: Python argument types in
    StatusEffect.AddCancellation(StatCreepEffect, str)
did not match C   signature:
    AddCancellation(class Game::StatusEffects::StatusEffect {lvalue}, class std:
:basic_string<char,struct std::char_traits<char>,class std::allocator<char> > {l
value})
  

Я не совсем уверен, в чем проблема. StatCreepEffect должен быть экземпляром StatusEffect, не так ли? И Boost::python автоматически обрабатывает преобразование строки, не так ли? Я неправильно вызываю метод? Такое ощущение, что я пропустил что-то маленькое, но я не уверен, что это такое. Будем признательны за любую помощь.

Ответ №1:

Оказывается, мне нужно иметь

 void AddCancellation(std::string amp;effect)
{
   CancelsEffects.insert(effect);
}
  

как

 void AddCancellation(const std::string amp;effect)
{
   CancelsEffects.insert(effect);
}
  

Ответ №2:

Я думаю, что проблема может заключаться в этом повышении.Python не совсем понимает, что StatusEffectWrapper является производным от StatusEffect. Если нет какой-либо причины, по которой вы указываете удерживаемый тип, я бы попробовал просто указать класс как:

 class_<StatusEffects::StatusEffectWrapper, boost::noncopyable>("StatusEffect")
    .def("AddCancellation", amp;StatusEffectWrapper::AddCancellation)
    ;