2

私は根本的な間違いを犯していると思いますが、私は一生それを見ることができません。

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はユニオンなので、NSInvocationによって返されるfloat値を取得できます。

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

これはデータオブジェクトのメソッドです(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 これは、解放されたメモリ、またはスコープ外のメモリにアクセスしていることを意味します。

ポインターへのポインターを追跡するのに迷っています。2つのfloat値は(他のメソッドの他の情報と同様に)正常に検出されfloat*ますが、パラメーターとしてaを要求するのはこれだけです。私が理解していることから、このconvertPixX:メソッドはMac OS 9用に作成されたCプログラムから変換されたものです...そのため、値としてc-arrayを要求しoutます...と思います。

とにかく、どんな洞察も大歓迎です。

私は次のような値を送信しようとしました:

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-に加えて、それは偽物で間違っていると確信しています。...しかし、私は試しました。

とにかく...ポインタ!クロスランゲージ!ああ!

ありがとう、

4

1 に答える 1

0

配列はポインタではありません。次の行を追加してみてください

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

すぐ真上に。

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

s2と&s2はどちらも配列の最初のフロートのアドレスであるため、次のようにします。

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

n = 2の場合、最初のfloatへのポインターをコピーしていませんが、最初のfloat、IDが64ビット幅の場合は最初の2つの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は、必要な二重間接参照を提供する実際のポインターです。

于 2010-10-01T13:34:46.757 に答える