0

我想这应该是可能的。我试过但找不到一个好的答案。我基本上想制作一个动态结构。我想读取一个文件,它告诉我我的结构将包含的数据类型。基于这些价值观,我想建立一个结构。我想为此使用 C++。我们可以将 oracle 视为一个示例,我们提供一个 csv 文件,它会识别它们应该是什么类型并制作该特定数据类型的列。

谁能帮我解决这个问题?

更新:我想我应该添加一点代码来解释我的问题陈述。所以我们开始:

//PLC Data Block Sturcture.
//Todo: try to construct this structure from a file or something
struct MMSDataHeader{
    bool          bHeader_Trigger;      //2
    unsigned char MachineTimeStamp[8];  //8
    std::string   Header_MachineID;     //12
    std::string   Header_Station;       //12
    int           Header_MessageID;     //2
    int           Header_MessageSequenceNo; //2
    int           Header_NumberOfProperties; //2
    int           MeasurementType;          //2
    bool          Response_Acknowledge;     //2
};
typedef struct MMSDataHeader MMSDataHeader;

int PLCBox::GetHeader(){

   MMSDataHeader local_PLCData = { 0 };
  int res = -1;

  std::cout << "Reading Head :";
  if ((p_s7Client_ == NULL))  {
    std::cerr << "TSnap7Client is not connected.\n";
  }

  res = p_s7Client_->DBRead(nb_db_num_, 0, k_header_size, (void *)(&buffer_));    
  //synchronous mode: default mode
  //inFile.read(buffer_, sizeof(buffer_));
  memcpy(&local_PLCData.bHeader_Trigger, buffer_, 1);
  memcpy(local_PLCData.MachineTimeStamp, buffer_ + 2, 8);
  memcpy(&local_PLCData.Header_MachineID, buffer_ + 10, 12);
  memcpy(&local_PLCData.Header_Station, buffer_ + 22, 12);
  memcpy(&local_PLCData.Header_MessageID, buffer_ + 34, 2);
  memcpy(&local_PLCData.Header_MessageSequenceNo, buffer_ + 36, 2);
  memcpy(&local_PLCData.Header_NumberOfProperties, buffer_ + 39, 2);
  memcpy(&local_PLCData.MeasurementType, buffer_ + 40, 2);
  memcpy(&local_PLCData.Response_Acknowledge, buffer_ + 42, 1);

  nb_props = local_PLCData.Header_NumberOfProperties;
  _b_read_trigger = local_PLCData.bHeader_Trigger;

  return local_PLCData.Header_NumberOfProperties;
}

这段代码现在对我有用,并在我调用 GetHeader 时解决了我的目的。正如大家所见,它正在从 PLC 中寻找准确的字节和结构。我想制作一个系统,以便可以从一个文件中制作结构,这样只有一个文件应该被替换,然后系统应该自己工作。我想我可以探索一些关于工厂设计模式的事情来做到这一点。现在我可以确定我的数据结构构造的文件类型和文件内容。有没有人在那边做过类似的事情。

4

3 回答 3

0

好吧,你几乎总是可以做一些事情——但你可能使用了错误的语言。正如 Max 指出的那样,C++ 是强类型的——其他语言,例如 PHP 不是——并且实际上可以改变类型。你可以做的,就像滚动你自己的语言一样,是覆盖你的数学运算符,如 +、- 等,这样你就有一个接受数据的基类 - 并确定它是否是浮点数、字符串、整数等,然后您可以像使用数字一样使用该对象。它们都将是您结构中的对象,但会覆盖数学等。为此需要做很多工作 - 但有一些关于覆盖数学运算符等的示例。

于 2018-02-14T14:53:17.250 回答
0

正如其他人所说,它不能完成,至少不能以最终得到具有正确类型的成员变量的结构或类的方式。

你可以做的是解析文件并从值的格式猜测数据类型,然后创建相应的类型(你必须为你想要支持的所有类型实现它),最后定义一个存储所有数据的数据结构具有不同类型的值(例如,将位置作为索引并使用 boost::any 作为值的向量)。

附带说明:
请注意,对于同一位置的值,您最终可能会得到不同类型的值,例如,如果一个值曾经写为“123”,一次写为“83.45”。第一个值可能会存储为某种整数,而第二个值可能会导致浮点数或双精度数。

于 2018-02-14T15:31:54.600 回答
0

在运行时构建 C++ 数据类型不太可能,因为 C++ 是一种静态类型语言。您最好使用 Python 或其他动态类型语言。但是,如果您将问题视为查找与键关联的值的任务,它是可行的,但生成的“结构”将远不及静态定义的 C++ 类型那么快。

对于单级结构(无子结构),您可以使用任何类型的键-> 值类,您希望这些类:std::map<std::string, std::pair<type, std::uniq_ptr<...>>>. 也就是说,作为字符串的键映射到对,其中第一个对成员标识值的类型,第二个对持有指向值本身的通用指针。如果您想要支持的类型数量有限,您可以编写一个动态调度程序,将引用转换为存储值的实际数据类型。

如果允许输入类型包含子结构,事情就会变得更加复杂。但鉴于存在用于半结构化数据的语言(参见 XML、JSON 等),您可以为任意复杂的结构化数据找到现成的解决方案。

于 2018-02-14T14:50:18.050 回答