2016-11-10 2 views
-1
// C lang 

#include <stdio.h> 

void func (void *ptr) { 
    int *iptr = ptr; 
    printf("{%d, %d, %d}\n", iptr[0], iptr[1], iptr[2]); 
} 

int main() 
{ 
    int ary[] = {111, 222, 333}; 
    func(&ary); 
    return 0; 
} 

=> выход: {111, 222, 333}Получить значение пустого указателя на массив

// Vala 

public void func (void *ptr) { 
    int *iptr = ptr; 
    print("{%d, %d, %d}\n", iptr[0], iptr[1], iptr[2]); 
} 

void main(string[] args) { 
    int[] ary = {111, 222, 333}; 
    func(&ary); 
} 

=> выход: {155115112, 155115112, 3}

???

Как получить значения указателя void для массива, в vala?

※ Использование void[] лучше, чем с использованием void*?

ответ

1

В коде примера C пустота * примерно эквивалентна с массивом байтов (некоторые порции памяти), так что вы можете сделать это:

public void func (uint8[] ptr) { 
    int[] iptr = (int[]) ptr; 
    print("{%d, %d, %d}\n", iptr[0], iptr[1], iptr[2]); 
} 

void main(string[] args) { 
    int[] ary = {111, 222, 333}; 
    func ((uint8[]) ary); 
} 

Это полностью типа небезопасных однако. Также Vala использует дополнительный скрытый параметр для длины, которая не задана длиной в байтах, а длина в элементах (но обычно sizeof(int) != sizeof(char)).

Я бы посоветовал найти другой способ сделать то, что ваша оригинальная проблема.

Этот вопрос звучит как типичный XY problem.

Использование голых указателей в Вале крайне неудобно (действительно, на каждом современном языке высокого уровня). Вместо этого вы должны использовать такие понятия, как контейнеры, ссылки, интеллектуальные указатели и т. Д.

Edit: Итак, вот почему ваш исходный код не работает и как это исправить:

Вы принимаете адрес чего-то, что уже является указателем здесь:

int[] ary = {111, 222, 333}; 
// ary is already a pointer, &ary will give you an int** 
func(&ary); 

Это только показывает, насколько опасно void* есть. Есть два способа исправить это (в то же время, используя void*):

  1. Возьмите адрес первого элемента:

    int[] ary = {111, 222, 333}; 
    func(&ary[0]); 
    
  2. Cast массив в указатель:

    int[] ary = {111, 222, 333}; 
    func((void*) ary); 
    

PS: void* может иметь разные значения в других контекстах (например, opaqu e указатели структуры или параметры ref/out или другие уродливые конструкции низкого уровня).

+0

Получение значений 'void *' в массив недоступно? –

+0

Вы можете отличить 'void *' от 'int []' просто отлично. Я отредактирую свой ответ, чтобы показать это. –

+0

Йенс абсолютно прав, не используя указатели в Вала. Если вы используете указатели в Vala для чего-то другого, кроме взаимодействия с привязкой, которая требует их (например, libxml), вы делаете это неправильно. – nemequ

Смежные вопросы