gpt4 book ai didi

c++ - NSInvocation 没有将指针传递给 C++ 数组

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:02:02 25 4
gpt4 key购买 nike

我认为我犯了一个根本性的错误,但我一生都看不到它。

我正在从 C++ 类(已锁定)中调用 Objective-C 对象的方法。我正在使用 NSInvocation 来防止我不得不编写数百个方法来访问这个其他对象中的数据。

这些是我正在经历的步骤。这是我的第一个电话,我想传递 s2。我无法真正提供可编译的示例,但希望这只是我的 DUHRRRRR 问题。

float s2[3];
id args2s[] = {(id)&_start.x(),(id)&_start.y(),(id)&s2};
_view->_callPixMethod(@selector(convertPixX:pixY:toDICOMCoords:),3,args2s);

这是被调用的 View 方法

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;
}

Invoke Union 是一个 union 体,因此我可以获得 NSInvocation 返回的浮点值。

union invokeUnion {
id OBJC_ID;
int intValue;
float floatValue;
bool boolValue;
};

这是数据Object中的方法(pthread用lock()和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;
}

DCMPix 对象(我无法修改,它是库的一部分)中的方法如下:

-(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];
}

它在尝试访问 d[0] 时崩溃。 BAD_EXC_ACCESS 我知道这意味着它正在访问已释放的内存或超出其范围的内存。

我迷失了跟踪指针的指针。这两个浮点值很好(其他方法中的其他信息也是如此),但这是唯一一个要求 float* 作为参数的方法。据我了解,convertPixX: 方法是从为 Mac OS 9 编写的 C 程序转换过来的...这就是为什么它要求将 c 数组作为 out值(value)……我认为。

无论如何,我们将不胜感激。

我试过像这样发送值:

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);

但这给出了一个 SIGKILL - 而且我确信它是假的和错误的。 ...但我试过了。

总之...指点!跨语言!啊!

谢谢,

最佳答案

数组不是指针。尝试添加以下行

NSLog(@"%p, %p", s2, &s2);

就在上面。

id args2s[] = {(id)&_start.x(),(id)&_start.y(),(id)&s2};

s2 和 &s2 都是数组中第一个 float 的地址,所以当你这样做时:

[invocation setArgument:args[n] atIndex:2+n];

对于 n = 2,您不是复制指向第一个 float 的指针,而是复制第一个 float ,如果 id 是 64 位宽,则可能是前两个 float 。

编辑:

要解决此问题,这可能有效(未测试)。

float s2[3];
float* s2Pointer = s2;
id args2s[] = {(id)&_start.x(),(id)&_start.y(),(id)&s2Pointer};
_view->_callPixMethod(@selector(convertPixX:pixY:toDICOMCoords:),3,args2s);

s2Pointer 是一个真正的指针,可以为您提供所需的双重间接寻址。

关于c++ - NSInvocation 没有将指针传递给 C++ 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3838961/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com