Je pense que je fais juste une erreur fondamentale, mais je ne peux pas pour la vie de moi le voir.NSInvocation ne passant pas le pointeur vers le tableau C++
J'appelle une méthode sur un objet Objective-C depuis une classe C++ (qui est verrouillée). J'utilise NSInvocation pour m'empêcher d'écrire des centaines de méthodes juste pour accéder aux données de cet autre objet.
Voici les étapes que je traverse. Ceci est mon premier appel, et je veux passer s2
. Je ne peux pas vraiment fournir un exemple compilable, mais j'espère que c'est juste un problème de DUHRRRRR de ma part.
float s2[3];
id args2s[] = {(id)&_start.x(),(id)&_start.y(),(id)&s2};
_view->_callPixMethod(@selector(convertPixX:pixY:toDICOMCoords:),3,args2s);
Ceci est la méthode de vue étant appelé
invokeUnion View::_callPixMethod(SEL method, int nArgs, id args[])
{
DataModule* data;
DataVisitor getdata(&data);
getConfig()->accept(getdata);
invokeUnion retVal;
retVal.OBJC_ID = data->callPixMethod(_index, _datasetKey, method, nArgs, args);
return retVal;
}
Union Invoke est une union que je peux obtenir la valeur de flotteur retourné par NSInvocation.
union invokeUnion {
id OBJC_ID;
int intValue;
float floatValue;
bool boolValue;
};
Ceci est la méthode dans l'objet de données (pthread verrouillé avec lock() et unlock());
id DataModule::callPixMethod(int index, std::string predicate, SEL method, int nArgs, id args[])
{
// May Block
DCMPix *pix =[[getSeriesData(predicate) pix] objectAtIndex:index];
lock();
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMethodSignature *signature;
NSInvocation *invocation;
signature = [DCMPix instanceMethodSignatureForSelector:method];
invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setSelector:method];
[invocation setTarget:pix];
if (nArgs > 0) for (int n = 0; n < nArgs; n++) {
SFLog(@"invocation: i=%d, *ptr=0x%x, valf=%f, vald=%d",n,args[n],*args[n],*args[n]);
[invocation setArgument:args[n] atIndex:2+n];
}
id retVal;
[invocation invoke];
[invocation getReturnValue:&retVal];
[pool release];
unlock();
return retVal;
}
La méthode dans l'objet DCMPix (que je ne peux pas modifier, il fait partie d'une bibliothèque) est la suivante:
-(void) convertPixX: (float) x pixY: (float) y toDICOMCoords: (float*) d pixelCenter: (BOOL) pixelCenter
{
if(pixelCenter)
{
x -= 0.5;
y -= 0.5;
}
d[0] = originX + y*orientation[3]*pixelSpacingY + x*orientation[0]*pixelSpacingX;
d[1] = originY + y*orientation[4]*pixelSpacingY + x*orientation[1]*pixelSpacingX;
d[2] = originZ + y*orientation[5]*pixelSpacingY + x*orientation[2]*pixelSpacingX;
}
-(void) convertPixX: (float) x pixY: (float) y toDICOMCoords: (float*) d
{
[self convertPixX: x pixY: y toDICOMCoords: d pixelCenter: YES];
}
Cela se briser quand il tente d'accéder à d[0]
. BAD_EXC_ACCESS
que je sais signifie qu'il accède à la mémoire libérée, ou à la mémoire en dehors de sa portée. Je suis en train de perdre la trace de mes pointeurs vers les pointeurs. les deux valeurs flottantes se rencontrent bien (comme d'autres informations dans d'autres méthodes) mais c'est la seule qui demande un float*
en tant que paramètre. D'après ce que je comprends la méthode convertPixX:
a été converti à partir d'un programme C écrit pour Mac OS 9 ... c'est pourquoi il demande le c-tableau comme une valeur out
... Je pense.
De toute façon, toute idée serait grandement appréciée.
J'ai essayé d'envoyer la valeur comme ceci:
float *s2 = new float[3];
void* ps2 = &s2;
id args2s[] = {(id)&_start.x(),(id)&_start.y(),(id)&ps2};
_view->_callPixMethod(@selector(convertPixX:pixY:toDICOMCoords:),3,args2s);
Mais cela donne une SIGKILL
- plus je suis sûr que c'est faux et le mal. ... mais j'ai essayé.
de toute façon ... pointeurs! langue croisée! argh!
Merci,
peut-être 'void * []' serait plus approprié – user102008