У меня есть странная проблема с установкой аргумента NSInvocation со структурой, которая содержит двойной или любой 64-разрядный тип, который не выровнен (я его компенсировал char в начале структуры). Проблема в том, что некоторые байты очищаются после установки аргумента. Эта проблема возникает на ARM7, но не в симуляторе iOS.iOS NSInvocation setArgument: atIndex: не работает со структурой в строках ARM
Я использую LLVM 3.0 и Xcode 4.2
Вот мой код и результаты испытаний:
NSInvocation + Extension.h
@interface NSInvocation (Extension)
+ (NSInvocation*) invocationWithTarget: (id)aTarget
selector: (SEL)aSelector
retainArguments: (BOOL)aRetainArguments, ...;
- (void) setArguments: (va_list)aArgList;
- (void) setArguments: (va_list)aArgList atIndex: (NSInteger)aIndex;
@end // NSInvocation (Extension)
NSInvocation + Extension.m
#import <objc/runtime.h>
#import "NSInvocation+Extension.h"
@implementation NSInvocation (Extension)
+ (NSInvocation*) invocationWithTarget: (id)aTarget
selector: (SEL)aSelector
retainArguments: (BOOL)aRetainArguments, ...
{
NSMethodSignature* signature = [aTarget methodSignatureForSelector: aSelector];
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature: signature];
if (aRetainArguments)
{
[invocation retainArguments];
}
[invocation setTarget: aTarget];
[invocation setSelector: aSelector];
va_list argList;
va_start(argList, aRetainArguments);
[invocation setArguments: argList];
va_end(argList);
return invocation;
}
- (void) setArguments: (va_list)aArgList
{
[self setArguments: aArgList atIndex: 0];
}
- (void) setArguments: (va_list)aArgList atIndex: (NSInteger)aIndex
{
// Arguments are aligned on machine word boundaries
const NSUInteger KOffset = sizeof(size_t) - 1;
UInt8* argPtr = (UInt8*)aArgList;
NSMethodSignature* signature = [self methodSignature];
// Indices 0 and 1 indicate the hidden arguments self and _cmd respectively.
for (int index = aIndex + 2; index < [signature numberOfArguments]; ++index)
{
const char* type = [signature getArgumentTypeAtIndex: index];
NSUInteger size = 0;
NSGetSizeAndAlignment(type, &size, NULL);
[self setArgument: argPtr atIndex: index];
argPtr += (size + KOffset) & ~KOffset;
}
}
@end // NSInvocation (Extension)
метод Объявите для вызова и структура данных
- (void) arg1: (char)aArg1 arg2: (char)aArg2 arg3: (TEST)aArg3 arg4: (char)aArg4;
typedef struct test {
char c;
double s;
char t;
void* b;
char tu;
} TEST;
телефонный код
TEST df = { 'A', 12345678.0, 'B', (void*)2, 'C' };
char buf[100] = {0};
NSInvocation* ik = [NSInvocation invocationWithTarget: self selector: @selector(arg1:arg2:arg3:arg4:) retainArguments: NO, '1', '2', df, '3'];
[ik getArgument: &buf atIndex: 4];
Содержание BUF на ARM7 (байт 8, 9, 10 и 11 набор для ноль, который испортил двойное значение)
41 00 00 00 00 00 00 00 29 8C 67 41 42 00 00 00 02 00 00 00 43 00 00 00
Содержание BUF на i386 тренажере (как ожидалось)
41 00 00 00 00 00 00 C0 29 8C 67 41 42 00 00 00 02 00 00 00 43 00 00 00