2013-10-01 4 views
0

У меня есть функция, которая возвращает double в void *. Однако, похоже, он потеряет указатель или кажется неспособным получить значение, поскольку он возвращает 0 из функции.Магазин double in void *

Как бы вы создали двойник и присвоили ему значение void *, а затем вернете его, не выходя из рамки.

Идея этой функции она будет преобразовывать объект из Objective-C к чему-то в C++, но не все в C++ является объектом таких как двойной, где он находится в Objective C.

void * IDToSTD (id anObject){ 

void * stdObject = NULL; 

if ([anObject class] == [PFObject class]) { 
    stdObject = BridgePFObject((void *)CFBridgingRetain(anObject)); 
    return stdObject; 
} 

CFTypeRef inTypeRef = (__bridge CFTypeRef)anObject; 
CFTypeID type = CFGetTypeID(inTypeRef); 

if (type == CFArrayGetTypeID()) { 
    std::vector<void *> arr = NSArrayToSTDVector([(NSArray *)anObject copy]); 
    stdObject = &arr; 
} else if (type == CFDictionaryGetTypeID()) { 
    std::map<std::string, void *> dict = NSDictionaryToSTDMap([(NSDictionary *)anObject copy]); 
    stdObject = &dict; 
} else if (type == CFStringGetTypeID()) { 
    stdObject = (char *)[(NSString *) anObject cStringUsingEncoding:NSUTF8StringEncoding]; 
} else if (type == CFNumberGetTypeID()) { 
    double *value = (double *)malloc(sizeof(double *)); 
    *value = [(NSNumber *)anObject doubleValue]; 
    stdObject = value; 
} else { 
    [NSException raise:@"Invalid object value" format:@"Object must be of basic Core Foundation or Parse Type, Object Type is: %@", NSStringFromClass([anObject class])]; 
} 

return stdObject; 

}

+4

Почему бы просто не вернуть «двойник»? –

+0

Является ли значение двойника, хранящегося в куче или стеке? (с помощью оператора 'new' или нет?) – Matthew

+0

Можете ли вы показать код? Вы компилируете 64-битную или 32-разрядную версию? Это звучит как ужасно ужасный способ сделать бизнес. Звучит так, будто вы можете попробовать: void * vp; двойной d = 3,14159; * (double *) & vp = d; 'или что-то столь же варварское. –

ответ

1

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

Назначение двойника непосредственно указателю, безусловно, дает проблемы в 32-битных приложениях (double = 8 bytes, pointer = 4 bytes).

Что вы можете сделать, так это объявить двойную переменную как статическую в вашей функции. Затем верните указатель на эту статическую двойную переменную. Однако, как только кто-то другой (другой поток?) Вызовет функцию, статический двойной будет перезаписан, и первый вызывающий абонент потеряет значение.

Проблему нити можно решить, используя локальное хранилище потоков. В Visual Studio вы можете использовать «declspec (thread)» для создания статической переменной static-per-thread. Но это все еще не решает проблему, если вы не можете гарантировать, что тот же поток будет вызывать одну и ту же функцию, если первый не удалил двойное значение из указателя void.

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