我有一个事件类,我试图使用Boost.Python在python中进行访问。这是列表,以及相关的宏和示例派生事件类。
class Event
{
private:
unsigned __int64 m_TimeStamp;
public:
// Empty parameter struct used as base for event parameters
// in derived classes.
struct Params { };
Event();
virtual unsigned int Type() const = 0;
virtual const char* TypeName() const = 0;
unsigned __int64 TimeStamp() const { return m_TimeStamp; }
};
typedef shared_ptr<Event> EventPtr;
#define DECLARE_EVENTTYPE(typeName, id) \
enum { TYPE = id }; \
unsigned int Type() const { return static_cast<unsigned int>(id); } \
const char* TypeName() const { return typeName; }
// Macro used to declare the start of an event parameters structure
#define START_EVENTPARAMS() struct Params : public Event::Params {
// Macro used to finish the event parameters structure declaration
#define END_EVENTPARAMS(eventName) \
} m_Params; \
eventName(const Event::Params* pkParams = NULL) : Event() \
{ \
if (NULL != pkParams) \
{ \
const eventName::Params* pkEventParams = \
reinterpret_cast<const eventName::Params*>(pkParams); \
if (NULL != pkEventParams) \
m_Params = *pkEventParams; \
} \
} \
static const eventName::Params& Parameters(const EventPtr pkEvent) \
{ \
const shared_ptr<eventName> pkErrorEvent( \
dynamic_pointer_cast<eventName>(pkEvent)); \
return pkErrorEvent->m_Params; \
}
// Macro used for events that have no parameters
#define EVENT_NOPARAMS(eventName) \
eventName(const Event::Params*) : Event() { }
struct ExampleEvent : public Event
{
START_EVENTPARAMS()
std::string m_strMsg;
END_EVENTPARAMS(ExampleEvent)
DECLARE_EVENTTYPE("ExampleEvent", 1);
};
目的是我希望能够从这个派生基于python的事件类,但是声明和使用事件参数的机制嵌入在宏中。坦率地说,我不认为它在C ++中的设置方式无论如何都会在python中运行,因为事件在python中的任何参数都可能存储在字典中。
有没有办法使用boost.python导出此功能,还是有更好的方法来设计适用于C ++和Python的通用参数支持的类?
答案 0 :(得分:0)
最终,Python没有真正的方法来创建新的C ++类型,这实际上就是你所要求的。如果您希望能够在Python中创建与C ++中创建的新事件类型相同的新事件类型,那么您将需要在C ++中使用更加动态的类似Python的结构。
如果您的要求确实只适用于C ++和Python(即您不打算将其扩展到其他语言),那么您可以考虑将事件参数存储在boost::python::dict
而不是单独的数据中成员。您需要在C ++中使用boost::python::extract<>
来访问值,否则它是一个非常干净的系统。 (你可以在模板化的访问器方法中隐藏提取调用。)
另一种选择是使用getter访问事件参数,例如Event::get_param<T>("name")
。如果你使这个虚拟化,那么基于Python的事件实现可以提供他们自己的版本。