2012-02-13 2 views
-1

Я звоню sysctl() для получения статистики в памяти и для аргумента void* oldVal, я передаю указатель на двойной. Однако вместо того, чтобы установить двойное значение в правильное значение, оно просто устанавливает его на 0,00000Использование парного разряда в Unix?

Однако, когда я пытаюсь сделать то же самое с длинным, он устанавливает его в правильный stat. Почему двойное значение устанавливается равным 0,00000, а время устанавливается на правильный stat?

int systemInfoNeeded[2] = {CTL_HW, HW_PHYSMEM}; 
    size_t sizeOfBuffer = sizeof(totalAmount); 

    if (sysctl(systemInfoNeeded, 2, &totalAmount, &sizeOfBuffer, NULL, 0)) 
    { 
     NSLog(@"Total memory stat retrieval failed.\n"); 
     exit (EXIT_FAILURE); 
    } 

totalAmount является двойной. Во-вторых, я меняю тип totalAmount на долгий, он отлично работает. Есть ли в любом случае, я могу заставить двойник работать? Я хочу напрямую отправить в totalAmount, а не отправлять длинный, а затем присваивать значение totalAmount.

Я использую Objective-C/C, на Mac OS X Snowleopard с Xcode 3.2.6

+0

Прочтите здесь код, чтобы узнать, как это сделать: http://www.opensource.apple.com/source/gcc/gcc-5484/libiberty/physmem.c –

ответ

1

sysctl() принимает указатель на тип, указанный в man-странице, для свойства, которое вы запрашиваете. Параметр объявляется как void *, так что один и тот же общий интерфейс может работать с различными типами, ожидаемыми различными свойствами. Это не означает, что вы можете использовать любой тип, который вам нужен. В случае HW_PHYSMEM это целое число, т. Е. Int, как следует из названия, не длинное или что-либо еще.

Единственная причина, по которой он работает, если вы передаете длинный, состоит в том, что macs мало endian, поэтому первые четыре байта значения как long такие же, как значение, как int, но вы, конечно, не должны зависеть от это.

Если вы хотите прочитать double, преобразуйте целое число.

Вы должны хорошо взглянуть на sysctl(3). Посмотрите, в частности, на пример с KERN_MAXPROC. Обратите внимание на использование int.

+0

Спасибо, это очень помогло – fdh

3

Вы не можете просто выбрать свой любимый тип данных и передать указатель на него; вызов sysctl ожидает указатель на целое число, и именно это вы должны предоставить. Если вы передадите указатель на double, то вы получите двойную с битами, которые представляют значение как целое число - результат - тарабарщина.

+0

sysctl не ожидает указателя на длинный. Он ожидает указатель на числовую переменную, поэтому он является недействительным *, а не длинным *. Если я передаю целое число, оно все равно работает, поэтому я не понимаю, почему двойной не будет. – fdh

+0

Но не любой указатель нужного вам типа, нет способа проверить, какой указатель вы прошли, поэтому вам нужно предоставить один из нужного типа. – JustSid

+1

Страница «BSD» для 'sysctl (3)' бесит. Почему он не говорит *, который * целочисленный тип использует так называемые «целочисленные» значения? Вы просто должны знать, что это 'long' (в отличие от' int', который не обязательно должен быть того же размера и представления, что и 'long', поскольку 64-битная OSX использует LP64), или вы должны проверить размер, записанный по каждому вызову, и если это 'sizeof (long)', вы можете переинтерпретировать данные как 'long', если это какой-то другой реинтерпрет размера, как какой-то другой целочисленный тип? –

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