2014-02-15 1 views
0

Я нашел много потоков об этом, но ни один из них не работает. Вероятно, это просто указатель mayem, где мне нужно разместить правильное количество звезд в нужном месте, но я не могу понять это.Возвращение и литье указателя массива (Ошибка: недопустимые типы ... для индекса массива)

Я хочу прочитать blob из базы данных SQLITE, которая изначально представляла собой трехмерный массив. 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 из первой записи в таблице (имеется только одна запись). Целевой массив - это p_map, который представляет собой трехмерный массив «unsigned char». Но SQLcolumn_blob возвращает const void *.

Так что моя идея заключалась в создании указателя на «unsigned char». Затем преобразуйте «const void *» в «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 lar.

+0

Ah! Понимаю. Я попытаюсь посмотреть, работает ли это. Я использую смесь C и C++, поэтому я не против бросать старый путь. – user3313505

+0

Я пробовал этот метод с реинтерпретом. Компиляция работала, но результаты не были желательными. Данные карты были рассеяны. Я закончил использовать метод 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 - это текст блоба, и вы хотите его полностью скопировать в 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'-ing над ним - плохая идея. – abligh

+0

Я попробовал второй метод с переменной Z, и он сработал. – user3313505

0

Как можно заметить, tmpmap действует как одно- мерный массив символов. Чтобы ваш код работал, вам нужно будет преобразовать 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