首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将void*转换为仅在运行时已知的几种类型

将void*转换为仅在运行时已知的几种类型
EN

Stack Overflow用户
提问于 2014-12-27 12:44:05
回答 2查看 216关注 0票数 1

我正在将我的C++程序连接到一个C++框架。

框架返回一个void*指针,指向使用malloc()初始化的一组数据:

代码语言:javascript
复制
void* getData() {
    return framework->returnPointer();
}

只有在运行时(从我的程序中)才知道数据的类型,框架具有以下功能:

代码语言:javascript
复制
size_t ndf_sizeof(ndf_typeid id) {
    switch(id) {
        case NDF_INT64:
            return sizeof(int64_t);
        case NDF_FLOAT:
            return sizeof(float);
        case NDF_DOUBLE:
            return sizeof(double);
    }
    return 0;
}

数据可以采取几种不同的类型,并且类型存储为ndf_type (即数据类型的整数标识符)。数据在运行时不会更改类型。我可以检索数据的ndf_type,也可以检索数据的大小。

我需要做两件事:

  1. 在运行时声明并初始化与数据类型相同的缓冲区。
  2. 迭代数据并将值放置到缓冲区中

在运行时才知道数据类型,而运行时数据类型本身可以采取几种不同的类型,这是我遇到的困难。我尝试过使用模板和通用数据结构,但没有效果。

我们非常感谢解决这个问题的办法。

EN

回答 2

Stack Overflow用户

发布于 2014-12-27 12:51:55

由于声明发生在编译期间,所以不能在运行时声明类型。

但是,您可以在编译期间声明所有可能的类型,准备这些类型的指针,并在运行时将其转换为适当的指针。根据你的要求,我要详细说明这一点。

我假设您有一个指针,例如: void * raw_data,并且您知道类型ndf_typeid id。

您可以这样分配所需的指针:

代码语言:javascript
复制
int64_t *p1 = 0;
float   *p2 = 0;
double  *p3 = 0;
switch(id) {
    case NDF_INT64:   p0 = (int64_t  *) raw_data; break;
    case NDF_FLOAT:   p1 = (float    *) raw_data; break;
    case NDF_DOUBLE:  p2 = (double   *) raw_data; break;
}

然而,真正的工作在那之后开始--你想做些什么,你会有很多"if“和"case”语句来执行你想要执行的代码。这就是为什么有时人们使用虚拟方法的原因:

代码语言:javascript
复制
struct Any {
   size_t _size;
   virtual void doit() = 0;
};

template < typename T > struct Typ: Any {
   T _data;
   Typ ( void * data ): _size(sizeof(T)), _data(*(T*)data) {}
   virtual void doit {
      cout << _data << " has size " << _size;
   }
}

Any * any = 0;

switch(id) {
   case NDF_INT64:   any = new Typ<int64_t> (raw_data); break;
   case NDF_FLOAT:   any = new Typ<float  > (raw_data); break;
   case NDF_DOUBLE:  any = new Typ<double > (raw_data); break;
}

any->doit();

这只会打印出值。然后,您可以为每个Typ覆盖doit:

代码语言:javascript
复制
template<> void Typ<float>::doit() {
   cout << "this is a float: " << _data;
}

这允许您根据类型进行不同的工作。

票数 4
EN

Stack Overflow用户

发布于 2014-12-27 12:54:37

在运行时声明并初始化与数据类型相同的缓冲区。

不,你不能这样做,因为你不知道什么类型实际上是数据。最近您可以做的是声明缓冲区以支持每种类型,然后在运行时决定需要填充哪个缓冲区。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27667347

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档