//注册创建者 模板< class T> void Register(int Id) { m_creators [Id] = CMDCreator< T> ;; } //取消注册创建者 bool取消注册(const int& Id) { 返回m_creators.erase(Id)== 1; } CMDBase *创建(unsigned char const * buffer) { // MSG_HEADER * msg_id = reinterpret_cast< MSG_HEADER *>(缓冲区); MSG_HEADER * msg_id; //只有在这里因为reinterpret_cast错误 投诉 //插入错误检查! return(m_creators [msg_id->来源])(缓冲区); } reinterpret_cast针对常量 缓冲区和非常量MSG_HEADER *生成错误。 ?? return(m_creators [msg_id-> source])(缓冲区); //返回这里可能是 a有点混乱 私有: typedef CMDBase *(* CMDCreator_t)(unsigned char const * ); 模板< class T> 静态CMDBase * CMDCreator(unsigned char const * buffer) { 返回新的T(缓冲区); } std :: map< int,CMDCreator_t> m_creators; }; int main(无效) { //调用一次,在初始化函数中: CMDFactory :: instance()。寄存器< MSG2_STATUS> (1); CMDFactory :: instance()。注册< MSG1_STATUS> (2); //在你的命令处理循环中: unsigned char buffer [512]; // Read_1553_Data(CHANNEL_FIVE,& ;缓冲区); CMDBase * newCommand = CMDFactory :: instance()。创建(缓冲区); // newCommand-> operation1(); //你想用它做什么 //可能把它添加到一个队列< CMDBase *>? //myqueue.push(newCommand); 返回EXIT_SUCCESS; } 解决方案 2003年10月2日03:57 :29 -0700, mp********@hotmail.com (MPowell)写道: 让我们假设new_command的返回值是MSG2_STATUS 我的意图是通过调用CMDHolder来记忆数据并且有一个函数''将检索''存储''数据的副本。后者我不确定该怎么办。有任何帮助。 好​​吧,我可以修复代码中的错误,但是你必须解释代码的意图 。你想用你收到的消息 怎么办?您是否需要根据收到的消息类型执行某些操作? CMDBase *创建(unsigned char const * buffer) { // MSG_HEADER * msg_id = reinterpret_cast< MSG_HEADER *>(缓冲区); MSG_HEADER * msg_id; //只有在这里因为reinterpret_cast错误 //插入错误检查! return(m_creators [msg_id-> source])(缓冲区); } 上面的函数应该更像这样: CMDBase *创建(unsigned char const * buffer) { MSG_HEADER const * msg_id = reinterpret_cast< MSG_HEADER const *>(缓冲区); map_t :: const_iterator i = m_creators。 find(msg_id-> source); if(i == m_creators.end()) { throw runtime_error("无效的来源); } 其他 { //通过指针调用创建函数。 /> 返回(i->秒)(缓冲区); } reinterpret_cast生成关于常量缓冲区的错误非常数MSG_HEADER *。 ?? 使标题const修复你的问题。 return(m_creators [msg_id-> source])(buffer); //返回这里可能会有点混乱 以上是通过函数指针实现的函数调用。 m_creators将源id映射到创建函数指针而不是 为该类型的消息创建Holder对象。上面访问 函数指针并调用函数,传递缓冲区。作为 的第一个参数。 tern中的该函数返回一个新的Holder对象, 用缓冲区初始化。 Tom MPowell写道: < snip> MSG2_STATUS _msg2_stat [2]; //用于双缓冲 MSG1_STATUS _msg1_stat [2]; //用于双缓冲 MSG1_CMD _msg1_cmd [2]; //用于双缓冲 typedef enum { _ msg1_cmd = 0, _ msg1_status, _ msg2_status } MSG_ID; 这些变量和枚举器中的每一个都是非法的。标识符 以下划线后跟小写字母开头保留 在全局命名空间中。 只是不要使用以下划线开头的标识符。这是避免这个问题最简单的方法。 -Kevin - 我的电子邮件地址有效,但会定期更改。 要联系我,请使用最近发布的地址。 >好吧,我可以修复代码中的错误,但你必须解释代码的意图。你想用你收到的消息怎么办?您是否需要根据收到的消息类型执行某些操作? 考虑 #define ID_ERROR_MASK 0x08 // #defined在翻译单元顶部 #define ID_MASK 0x07 // #defined在翻译单元顶部 int _msg2_header_error_count = 0; int _msg1_header_error_count = 0; int _msg2_message_index = 0; int _msg1_message_index = 0; //更多 struct _MSG2_STATUS //这里是演示和批次更多这些 { //为了简单而剥离''东西''。 unsigned int idx:1; unsigned int ldx:32; } MSG2_STATUS; MSG2_STATUS _msg2_message [2]; //用于双缓冲 //更多 创建函数将查看msg_id(它确实如此)然后检查 $ b错误$ b。 if(msg_id& ID_ERROR_MASK)== 0) { //如果没有错误看看msg_type MSG_HEADER msg_type = ((((msg_id>> 4)& ID_MASK)<< 3))| (msg_id& ID_MASK); 让我们假设现在msg_type映射到上面定义的MSG2_STATUS 开关(msg_type) { case _msg2_status://得到状态2消息 //双缓冲它 i = _msg2_message_index ^ 1; memcpy(& _msg2_message [i],buffer,sizeof(MSG2_STATUS)); _msg2_message_index ^ = 1; _msg2_message_ready = TRUE; 休息; case _msg1_status://获得状态1消息 //双缓冲它 i = _msg1_message_index ^ 1; memcpy(& _msg1_message [i],buffer,sizeof(MSG1_STATUS)); _msg1_message_index ^ = 1; _msg1_message_ready = TRUE; 休息; //等等 默认: 休息; } 其他 { switch(msg_id) { case _msg2_header_error://收到状态2消息 _msg2 _header_error_count ++; printf(" msg2_header_error =& d",msg2_header_error); break; case _msg1_header_error://收到状态2消息 _msg1_header_error_count ++; //我怀疑通过计数器会是谨慎的。 通过++ ostream方法有值回收 printf(" msg1_header_error =& d",msg1_header_error); break; //等等 默认值: 休息; } } 现在,双重缓冲数据,增加一个计数器,然后设置一个标志 - 没有错误。对于错误,请增加错误计数器。当前 模板样式的方法肯定更优雅 类中的单独函数应检索最新的 双缓冲区数据。我怀疑(假设我理解模板)每个 缓冲数据将被推到一个容器/持有人/ ??当需要 (120hz处理rountine检索最新的)时,通过调用某个函数来检索 ,模板参数为 结构。 最后,各个结构构成了整个结构的一部分。即 struct OVERALL { MSG1_TYPE msg1; MSG2_TYPE msg2; 还有更多。 } 一个单独的函数将检索''整体''。 本质上,一个获取数据并保存 请求者数据的模板 CMDBase * Create(unsigned char const * buffer) { // MSG_HEADER * msg_id = reinterpret_cast< MSG_HEADER *>(缓冲区); MSG_HEADER * msg_id; //只有在这里因为reinterpret_cast错误 //插入错误检查! return(m_creators [msg_id-> source])(缓冲区); } 上面的函数应该更像这样: CMDBase * Create(unsigned char const * buffer) { MSG_HEADER const * msg_id = reinterpret_cast< MSG_HEADER const *>(缓冲区); map_t :: const_iterator i = m_creators.find(msg_id-> source); map_t错误? ? if(i == m_creators.end()) {抛出runtime_error(无效的来源); } else { //通过指针调用create函数。 return(i-> second)(缓冲区); } reinterpret_cast相对于常量缓冲区和非常量MSG_HEADER *生成错误。 ?? 使标题const修复你的问题。 return(m_creators [msg_id-> source])(buffer); //返回这里可能会有点混乱 以上是通过函数指针实现的函数调用。 m_creators将源id映射到创建函数指针比可以为该类型的消息创建Holder对象。以上访问函数指针并调用函数,传递缓冲区。作为的第一个参数。这个函数在tern中返回一个新的Holder对象,用缓冲区初始化。 Tom Tom,真正适用于援助。如有必要,请随时使用我的电子邮件 地址。 Lets suppose the return value on new_command is MSG2_STATUS My intent then is to memcpy the data via the call to CMDHolder andhave a function that''ll retrieve a copy of the ''stored'' data. Thelatter I''m unsure how to do. Any help appreaciated.#include <iostream>#include <map>using namespace std; int msg2_status_index = 0;int msg1_status_index = 0;int msg1_cmd_index = 0; MSG2_STATUS _msg2_stat[ 2 ]; // used for double bufferingMSG1_STATUS _msg1_stat[ 2 ]; // used for double bufferingMSG1_CMD _msg1_cmd[ 2 ]; // used for double buffering typedef enum{_msg1_cmd = 0,_msg1_status,_msg2_status} MSG_ID; typedef struct // this is ++. Why use typedef. ''details'' I suppose{MSG_ID source;unsigned int msg_length : 12;unsigned int count : 4;} MSG_HEADER; typedef struct _MSG2_STATUS{MSG_HEADER header;unsigned int idx : 1;unsigned int jdx : 3;unsigned int kdx : 4;unsigned int spare : 24;unsigned int ldx : 32;} MSG2_STATUS; typedef struct _MSG1_STATUS{MSG_HEADER header;unsigned int idx : 1;unsigned int jdx : 3;unsigned int kdx : 4;unsigned int spare : 8;} MSG1_STATUS; typedef struct _MSG1_CMD{MSG_HEADER header;unsigned int idx : 1;unsigned int jdx : 3;} MSG1_CMD; class CMDBase{public:virtual ~CMDBase(){}/* what operations do you perform on these commands?virtual void operation1() = 0;virtual void operation2() = 0; */};template <class CMD>class CMDHolder: public CMDBase{public:CMDHolder(unsigned char const* buffer){memcpy(&m_CMDStruct, buffer, sizeof m_CMDStruct);} /* virtual void operation1(){//use overloaded global functions?structOperation1(m_CMDStruct);} virtual void operation2(){structOperation2(m_CMDStruct);} */private:CMD m_CMDStruct;}; class CMDFactory{public:static CMDFactory& instance(){CMDFactory fact;return fact;} // Register the creatortemplate <class T> void Register(int Id){m_creators[Id] = CMDCreator<T>;}// unregister creatorbool Unregister( const int& Id ){return m_creators.erase( Id ) == 1;} CMDBase* Create(unsigned char const* buffer){//MSG_HEADER* msg_id = reinterpret_cast<MSG_HEADER*>(buffer);MSG_HEADER* msg_id; // only here because reinterpret_cast errorcomplaint //insert error checking!return (m_creators[msg_id->source])(buffer);}reinterpret_cast generates an error with respect to the constantbuffer and the non constant MSG_HEADER*. ?? return (m_creators[msg_id->source])(buffer); // return here might bea bit confusing private:typedef CMDBase* (*CMDCreator_t)(unsigned char const*); template <class T>static CMDBase* CMDCreator(unsigned char const* buffer){return new T(buffer);} std::map<int, CMDCreator_t> m_creators;}; int main ( void ){//called once, in initialization function:CMDFactory::instance().Register<MSG2_STATUS> (1);CMDFactory::instance().Register<MSG1_STATUS> (2);// inside your command processing loop:unsigned char buffer[512];// Read_1553_Data(CHANNEL_FIVE, &buffer);CMDBase* newCommand = CMDFactory::instance().Create(buffer); // newCommand->operation1(); //whatever you want to do with it//maybe add it to a queue<CMDBase*>?//myqueue.push(newCommand); return EXIT_SUCCESS;} 解决方案 On 2 Oct 2003 03:57:29 -0700, mp********@hotmail.com (MPowell) wrote: Lets suppose the return value on new_command is MSG2_STATUSMy intent then is to memcpy the data via the call to CMDHolder andhave a function that''ll retrieve a copy of the ''stored'' data. Thelatter I''m unsure how to do. Any help appreaciated.Well, I can fix the errors in the code, but you''ll have to explainwhat the code is meant to do. What do you want to do with the messagesthat you receive? Do you need to perform some action depending on thetype of message you receive? CMDBase* Create(unsigned char const* buffer) { //MSG_HEADER* msg_id = reinterpret_cast<MSG_HEADER*>(buffer); MSG_HEADER* msg_id; // only here because reinterpret_cast errorcomplaint //insert error checking! return (m_creators[msg_id->source])(buffer); }The above function should go more like this: CMDBase* Create(unsigned char const* buffer){MSG_HEADER const* msg_id = reinterpret_cast<MSG_HEADERconst*>(buffer);map_t::const_iterator i = m_creators.find(msg_id->source);if (i == m_creators.end()){throw runtime_error("Invalid source");}else{//call create function through pointer.return (i->second)(buffer);}reinterpret_cast generates an error with respect to the constantbuffer and the non constant MSG_HEADER*. ??Making the header const fixes your problem.return (m_creators[msg_id->source])(buffer); // return here might bea bit confusing The above is actuall a function call made through a function pointer.m_creators maps source id onto a creation function pointer than cancreate the Holder object for messages of that type. The above accessesthat function pointer and calls the function, passing "buffer" as thefirst parameter. That function in tern returns a new Holder object,initialized with the buffer. TomMPowell wrote: <snip> MSG2_STATUS _msg2_stat[ 2 ]; // used for double buffering MSG1_STATUS _msg1_stat[ 2 ]; // used for double buffering MSG1_CMD _msg1_cmd[ 2 ]; // used for double buffering typedef enum { _msg1_cmd = 0, _msg1_status, _msg2_status } MSG_ID; Every one of these variables and enumerators is illegal. Identifiersbeginning with an underscore followed by a lowercase letter are reservedin the global namespace. Just don''t use identifiers beginning with an underscore. It''s theeasiest way to avoid this problem. -Kevin--My email address is valid, but changes periodically.To contact me please use the address from a recent posting. > Well, I can fix the errors in the code, but you''ll have to explain what the code is meant to do. What do you want to do with the messages that you receive? Do you need to perform some action depending on the type of message you receive?Consider #define ID_ERROR_MASK 0x08 // #defined at top of the translation unit#define ID_MASK 0x07 // #defined at top of the translation unitint _msg2_header_error_count = 0;int _msg1_header_error_count = 0; int _msg2_message_index = 0;int _msg1_message_index = 0;// lots more struct _MSG2_STATUS // here for demo and lots more of these{// for simplicity strip out ''stuff''.unsigned int idx : 1;unsigned int ldx : 32;} MSG2_STATUS; MSG2_STATUS _msg2_message[ 2 ]; // for double buffering// lots more The Create function will look at the msg_id (which it does) then checkfor error. if (msg_id & ID_ERROR_MASK) == 0 ){// if no error look at msg_typeMSG_HEADER msg_type =(((( msg_id >> 4 ) & ID_MASK ) <<3 )) | ( msg_id &ID_MASK ); Lets suppose now the msg_type maps to MSG2_STATUS defined above switch (msg_type){case _msg2_status: //got a status 2 message // double buffer iti = _msg2_message_index ^ 1;memcpy( &_msg2_message[i], buffer, sizeof(MSG2_STATUS) );_msg2_message_index ^= 1;_msg2_message_ready = TRUE;break; case _msg1_status: //got a status 1 message // double buffer iti = _msg1_message_index ^ 1;memcpy( &_msg1_message[i], buffer, sizeof(MSG1_STATUS) );_msg1_message_index ^= 1;_msg1_message_ready = TRUE;break;// and so ondefault:break;}else{switch( msg_id ){case _msg2_header_error: //got a status 2 message_msg2_header_error_count++;printf (" msg2_header_error = &d ", msg2_header_error);break;case _msg1_header_error: //got a status 2 message_msg1_header_error_count++; // I suspect it''d be prudent to pass in the counters andhave values returend by the ++ ostream approachprintf (" msg1_header_error = &d ", msg1_header_error);break;// and so ondefault:break;}} So now, double buffer the data,increment a counter, then set a flag -for no errors. For errors, increment an error counter. The currenttemplate style approach is certainly more elegant A separate function within the class should retrieve the most currentdouble buffer data. I suspect (assuming i understand templates) eachbuffered data will be ''pushed'' into a container/holder/?? and whennecessary (a 120hz processing rountine retrieves the latest) retrievedvia a call to some function with the template parameter being theappropriate struct. Lastly, the individual structs form a part of an overall struct. iestruct OVERALL{MSG1_TYPE msg1;MSG2_TYPE msg2;lots more.} A separate function will retrieve the ''overall''. In essence, a template to ''get'' the data and hold data for therequestor CMDBase* Create(unsigned char const* buffer) { //MSG_HEADER* msg_id = reinterpret_cast<MSG_HEADER*>(buffer); MSG_HEADER* msg_id; // only here because reinterpret_cast errorcomplaint //insert error checking! return (m_creators[msg_id->source])(buffer); } The above function should go more like this: CMDBase* Create(unsigned char const* buffer) { MSG_HEADER const* msg_id = reinterpret_cast<MSG_HEADER const*>(buffer); map_t::const_iterator i = m_creators.find(msg_id->source); map_t error ?? if (i == m_creators.end()) { throw runtime_error("Invalid source"); } else { //call create function through pointer. return (i->second)(buffer); }reinterpret_cast generates an error with respect to the constantbuffer and the non constant MSG_HEADER*. ?? Making the header const fixes your problem.return (m_creators[msg_id->source])(buffer); // return here might bea bit confusing The above is actuall a function call made through a function pointer. m_creators maps source id onto a creation function pointer than can create the Holder object for messages of that type. The above accesses that function pointer and calls the function, passing "buffer" as the first parameter. That function in tern returns a new Holder object, initialized with the buffer. Tom Tom, truly appreaciate the assistance. Feel free to use my emailaddress if necessary. 这篇关于实施细节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-12 06:20