2015-12-18 3 views
0

У меня есть функция foo (void * pBuf). Мне нужно передать ему 64-битный адрес, но я не могу получить правильный тип, когда я передаю значение.Аргумент типа uint64_t несовместим с параметром типа void *

Пример: foo (адрес). Where- uint64_t address = 0x00000000DEADBEEF

EDIT: Компиляция с использованием компилятора ARM.

uint64_t foo(void *pBuf){ 
    uint64_t retAddr = (uint64_t) pBuf; 
    retAddr += 0x100000; 
    return retAddr; 
} 

Я на 32-битном ARM и sizeof(void *) является 4

Разъяснение: Почему мне нужен 64-битный адрес, на 32-битном ARM? Поскольку моя карта памяти использует 36-битную адресацию.

+0

Адрес - это локальная переменная, которая содержит адрес, который мне нужен. –

+0

Вам нужно будет предоставить более подробную информацию о какой системе вы находитесь и что делает функция 'foo' с ее аргументом –

+0

В чем проблема в вашем последнем примере кода? Единственная проблема, которую я могу догадаться, состоит в том, что некоторые компиляторы будут выдавать предупреждения путем литья непосредственно из 'void *' в 'uint64_t'. В таком случае предпочитайте двойное нажатие: '(uint64_t) (size_t)' – Cyan

ответ

0

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

  1. Foo ((недействительными *) (uint32_t) адрес)

Это работает только потому, что мой вход обув всегда 32-битное значение , Возвращаемое значение может быть 64-битным.

  1. Конечно, правильным исправить было бы изменение самого foo, если бы я мог его модифицировать. Я мог бы просто передать foo (& адрес). Внутри foo, retAddr = * pBuf.

Спасибо за все предложения!

0

Вызов это таким образом:

uint64_t address = 0xDEADBEEF; 
foo((void*)address); 

То есть, вы отливать адрес в ничтожной-указатель, чтобы быть совместимым с функцией подписи.

+2

Это приводит к неопределенному поведению в системах с 32-битным 'void *' –

+0

Пробовал это уже. Кажется, что не работает с armcc –

+0

@ M.M: Это неуместно, потому что OP уже сказал, что у них 64-битный адрес. 32-разрядные системы не имеют 64-разрядных адресов. –

0

Вы не должны использовать 64-разрядный тип для адреса, так как это неопределенное поведение для 32-разрядных (или любых не 64-разрядных) систем.

Скорее, предпочитают использовать uintptr_t, который является стандартом C. См this question для получения более подробной информации или this page для ссылок.

Тогда решение может быть:

uintptr_t address = 0xDEADBEEF; /* will trigger a warning if the constant is > max possible memory size */ 
foo((void*)address); 

Примечание: если uintptr_t не доступен в вашей системе, size_t обычно является хорошим вторым выбором.

Часть 2:

Похоже, в вашем перефразированном вопросе вы хотите преобразовать адрес в 64-битное целое число.

В этом случае прямая трансляция из ptr в integer может вызвать предупреждение о компиляторе из-за потенциальных различий в широте.

Предпочитают двойной бросок: uint64_t value = (uint64_t)(size_t) ptr;

+0

Мне нужен 64-разрядный адрес, хотя для AXI-адресации –