2009-07-27 22 views
1

PTHotKeyLibを64ビットに変更する作業を進めていますが、わからないコードで問題が発生しました周りを回る方法。 PTHotKeyCenterでは、registerHotKeyメソッドはEventHotKeyIDインスタンスを作成し、次にPTHotKeyオブジェクトをid属性に埋め込みます。元のコードは長い間使用されていました。 Appleの64ビットプログラミングガイドに従って、NSIntegerに変換しました。64ビット変換で異なるサイズの整数からポインタへのキャストを解決する

- (BOOL)registerHotKey:(PTHotKey *)theHotKey { 
    OSStatus error; 
    EventHotKeyID hotKeyID; 
    EventHotKeyRef carbonHotKey; 
    NSValue *key = nil; 

    if ([[self allHotKeys] containsObject:theHotKey]) 
    [self unregisterHotKey:theHotKey]; 

    if (![[theHotKey keyCombo] isValidHotKeyCombo]) 
    return YES; 

    hotKeyID.signature = kHotKeySignature; 
    hotKeyID.id = (NSInteger)theHotKey; 
    ... //Rest is not relevant 
    } 

ユーザーはホットキーをトリガすると、それはsendCarbonEventを呼び出します。EventHotKeyIDのうち、PTHotKeyインスタンスを引っ張るしようとする方法。これは、32ビットの土地で働いていたが、64ビットに対してコンパイルするとき、それは

x86_64版からの切り替え
- (OSStatus)sendCarbonEvent:(EventRef)event { 
    OSStatus error; 
    EventHotKeyID hotKeyID; 
    SGHotKey *hotKey; 

    NSAssert(GetEventClass(event) == kEventClassKeyboard, @"Unknown event class"); 

    error = GetEventParameter(event, 
          kEventParamDirectObject, 
          typeEventHotKeyID, 
          nil, 
          sizeof(EventHotKeyID), 
          nil, 
          &hotKeyID); 
    if (error) 
    return error; 

    NSAssert(hotKeyID.signature == kHotKeySignature, @"Invalid hot key id"); 
    NSAssert(hotKeyID.id != 0, @"Invalid hot key id"); 

    hotKey = (SGHotKey *)hotKeyID.id; // warning: cast to pointer from integer of different size 
// Omitting the rest of the code 
} 

警告「異なるサイズの整数からポインタへのキャスト」を与えるバックI386にコンパイル警告、すべてを削除し、正しく動作します。 x86_64の下では、クラッシャーが発生し、その問題を回避する方法がわかりません。どのようにそれを解決するための任意の提案?

答えて

4

ポインタと整数間のキャストは、移植性のないコードになるため、お勧めしません。

C99が「未定義の動作」と定義していることが何をしているのですか。これは基本的には動作する可能性があり、そうでないかもしれないことを意味します。 C言語は、あなたが入力したときに何をしているのかを暗黙のうちに知っていると仮定して、暗黙のうちにあなたが魔法のように何かをするのが安全かどうか知りたい37337これとそうでないときに。

これは、これがではなく、だった時代の1つであると言っても過言ではありません。

コンテキストからの問題は、おそらく、intサイズの変数に64ビットのポインタをキャストすることによるものです。 Mac OS X 64ビットABIはLP64と呼ばれ、longpointerは64ビット幅で、intは32ビット幅です。つまり、あなたのpointerintのうちの1つの間に、再び上の32ビットを切り落としました。これは本当に重要なことでした。

ドキュメントを見ると、idのタイプはUInt32です。だから、短い答えは、32ビットの整数に64ビットのポインタを置くことができないということです。

1

古典的な答えは、辞書や何かを作って、idの辞書にキーを置いて、値の中にポインタを置いて、32ビットidに実際のポインタを置かないようにすることです。

しかし、あなたはまだそれを解決しましたか?

+0

ポインタを保持するには小さすぎる変数へのポインタを置くにはどんなへのポインタが、動作しませに行くのではありません。 –

1

PTHotKeysLibと同じ問題が発生しました。それはx86_64アーチにのみ現れます。

解決するには、上記のようにキャストを実行する代わりに、64ビットオブジェクトの32ビットポインタへの参照を格納するSGHotKeysLibを調べました。 32ビットポインタが見つかると、32ビットポインタ(この場合はEventHotKeyID)への参照を見つけるために、すべての64ビットオブジェクト(この場合はSGHotKey)をループします。)

さらに参照:https://github.com/secondgear/SGHotKeysLib/blob/master/SGHotKeysLib/SGHotKeyCenter.m

for (SGHotKey *thisHotKey in [self allHotKeys]) { 
    if ([thisHotKey matchesHotKeyID:hotKeyID]) { 
     hotKey = thisHotKey; 
     break; 
    } 
    } 
関連する問題