Wednesday, 18 September 2013

EXC_BAD_ACCESS when using FFI to launch objc_sendmessagesuper

EXC_BAD_ACCESS when using FFI to launch objc_sendmessagesuper

id verify_object(id self, SEL _cmd, ...){
Class objectClass = object_getClass(self);
Class super = class_getSuperclass(objectClass);
Method method;
if ((method = class_getClassMethod(super, _cmd)) != NULL) {
NSLog(@"Verifying +[%s %s]", class_getName(objectClass),
sel_getName(_cmd));
} else {
method = class_getInstanceMethod(super, _cmd);
NSLog(@"Verifying -[%s %s]", class_getName(objectClass),
sel_getName(_cmd));
}
//Verfication Code Goes Here
int numberOfArgs = method_getNumberOfArguments(method);
ffi_cif cif;
ffi_type * args[numberOfArgs];
void * values[numberOfArgs];
int i = 1;
id vaarg;
va_list vaargs;
va_start(vaargs, _cmd);
struct objc_super superStruct = {self, super};
args[0] = &ffi_type_pointer;
values[0] = &superStruct;
while ((vaarg = va_arg(vaargs, id)) != nil) {
args[i] = &ffi_type_pointer;
values[i] = &vaarg;
i++;
}
char methodType[256];
method_getReturnType(method, methodType, 256);
NSLog( @"Return type: <%s>", methodType);
ffi_type * typePointer = NULL;
if (!strcmp( methodType, "v" )){
NSLog(@"Calling Void Function");
typePointer = &ffi_type_void;
} else {
NSLog(@"Calling Object Returning Function");
typePointer = &ffi_type_pointer;
}
id ret;
/* Initialize the cif */
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, numberOfArgs, typePointer, args)
== FFI_OK)
{
ffi_call(&cif, FFI_FN(objc_msgSendSuper), &ret, values);
}
va_end(vaargs);
free(methodType);
return ret;
}

No comments:

Post a Comment