2014-02-15 31 views
0

我发现很多关于此的线程,但它们都不起作用。这可能只是一个指针mayem我需要在正确的地方放置正确数量的星星,但我无法弄清楚。返回并投射数组指针(错误:无效类型...对于数组下标)

我想从最初是3维数组的SQLITE数据库中读取一个blob。 Sqlite返回一个“const void *”,我需要将其转换为一个临时表指针,以便我可以将其转换为真正的表。但我得到一个:

error: invalid types ‘unsigned char[int]’ for array subscript 

当试图将值从表转移到另一个。这是一个代码示例。

注意:以SQL ...为前缀的函数是SQLITE的私有包装,它们应该完美地工作。

void Map::load (void) 
{ 
    int i, j, k; 
    int errorsql; 
    unsigned char *tmpmap; //[ Map_MAXDEPTH ] [ Map_MAXWIDTH ] [ Map_BYTE_WIDTH ]; 

    SQLactivate_errormsg(); 

    errorsql = SQLprepare ("SELECT * FROM handmap;"); 

    if (errorsql == SQLITE_OK) 
    { 
     errorsql = SQLstep(); 

     if (errorsql == SQLITE_ROW) 
     { 
     tmpmap = (unsigned char*) SQLcolumn_blob (1); // return the pointer to the blob 

     for (k = 0 ; k < Map_MAXDEPTH; k++) 
      for (j = 0 ; j < Map_MAXWIDTH; j++) 
       for (i = 0; i < Map_BYTE_WIDTH; i++) 
       { 
        p_map [ k ][ j ][ i ] = *tmpmap [ k ] [ j ] [ i ]; // try to copy from a table to another. Compiler fails here. 
       } 
     } 
     else 
     printf ("Map.load: Cannot step into the DB\n"); 

     SQLfinalize(); 
    } 
    else 
     printf ("Map.load: Cannot Prepare statement to save map into the DB\n"); 

    SQLdeactivate_errormsg(); 
} 

该代码非常简单,它试图从表中的第一个条目(只有1个条目)读取列1。目标数组是p_map,它是一个“无符号字符”的三维数组。但是SQLcolumn_blob返回一个const void *。

所以我的想法是创建一个指向“无符号字符”的指针。然后将“const void *”转换为“unsigned char *”。然后使用unsigned char指针作为数组。但看来:

*tmpmap [ k ] [ j ] [ i ]; 

是非法的。我不能使用指针并将其重新解释为数组。所以这是虽然部分,因为数组是指针,但声明不同。

谢谢你的帮助。

回答

0

定义tmpmap作为

const unsigned char (*tmpmap)[ Map_MAXWIDTH ] [ Map_BYTE_WIDTH ]; 

另外,如果程序是用C++编写,然后更改此声明

tmpmap = SQLcolumn_blob (1); 

tmpmap = reinterpret_cast<const unsigned char (*)[ Map_MAXWIDTH ] [ Map_BYTE_WIDTH ]>(SQLcolumn_blob (1)); 

至于错误,那么很明显,你可能不会使用带有三个下标的tmpmap,因为tmpmap [i]有unsigned char类型,并且是sca幼儿型。

+0

啊!我懂了。我会试着看看它是否有效。我使用C和C++的混合体,所以我不介意以旧的方式投射。 – user3313505

+0

我试着用reinterpret强制转换这个方法。汇编工作,但结果并不如人意。地图数据被分散。我结束了使用abligh的方法 – user3313505

1

你不显示p_map的分配位置,但是你说它是一个无符号字符的'3D'数组。如果是的话,应该声明如下:

unsigned char p_map[Map_MAXDEPTH][Map_MAXWIDTH][Map_BYTE_WIDTH]; 

从你的代码的一些其他位,它看起来可能是char *数组,但肯定是有一些混乱这里:

 for (k = 0 ; k < Map_MAXDEPTH; k++) 
     for (j = 0 ; j < Map_MAXWIDTH; j++) 
      for (i = 0; i < Map_BYTE_WIDTH; i++) 
      { 
       p_map [ k ][ j ][ i ] = *tmpmap [ k ] [ j ] [ i ]; // try to copy from a table to another. Compiler fails here. 
      } 

我认为你说tmpmap是一个文本blob,你想完全复制到p_map。这样做会简单的最简单的方法:

memcpy (p_map, tmpmap, Map_MAXDEPTH * Map_MAXWIDTH * Map_BYTE_WIDTH * sizeof(char)); 

说明sizeof(char)乘法是因为它是保证1技术上没有用的。

如果你正在尝试做一个循环副本,不想依靠内存布局是相同的,为什么不干脆:

 int z = 0; 
    for (k = 0 ; k < Map_MAXDEPTH; k++) 
     for (j = 0 ; j < Map_MAXWIDTH; j++) 
      for (i = 0; i < Map_BYTE_WIDTH; i++) 
      { 
       p_map [ k ][ j ][ i ] = tmpmap[z++]; 
      } 
+0

p_map是一个对象变量,但你有定义的权利。 memcpy很有趣,因为我对文本阅读功能也一样。这只是我不确定3D阵列如何对齐实际内存中的数据。我会尝试他们两个。 – user3313505

+0

如果'p_map'是一个具有虚函数的对象,那么'memcpy'就不是个好主意。 – abligh

+0

我试着第二种方法与Z变量,它的工作。 – user3313505

0

因为它的立场,tmpmap充当单二维数组的char。为了让你的代码工作,你必须将k,j和i转换为单个数组索引。例如:

int ind = i +(j * Map_BYTE_WIDTH)+(j * Map_BYTE_WIDTH * Map_MAXWIDTH); p_map [k] [j] [i] = tmpmap [ind];

我想这样做。或者,您可以定义一个适当大小的3D数组类型,并根据该类型定义tmpmap。现在还不能看得太清楚......

+0

问题是我无法控制SQLcolumn_blob返回的指针类型。不过,我可以创建一个包含3D数组的结构,并且该函数应返回指向结构的指针。 – user3313505