2012-01-06 4 views
6

私はmethod_copyReturnType()によって返される型指定子を持っていると仮定します。 GCCで提供されるGNUランタイムには、objc_sizeof_type(),objc_alignof_type()などのような型指定子で動作するさまざまな方法があります。objective-c型指定子を解釈する方法(method_copyReturnType()によって返されるなど)

Appleランタイムを使用する場合、そのような方法はありません。

Appleランタイムを使用してのif/elseまたはcaseスイッチを実装せずにタイプ指定文字列を解釈するにはどうすればよいですか?

[更新]

私はアップル財団を使用することはできませんよ。

答えて

2

afaikの場合、バイナリにその情報を書き込む必要があります。構造体のsizeofとalignofを返す関数を作成し、サポートしなければならない型をサポートしてから、その関数(またはクラスメソッド)を呼び出します。

以下のプログラムは、多くのプリミティブがただ1文字であることを示しています。したがって、関数の実装の大半はスイッチになる可能性があります。

static void test(SEL sel) { 
    Method method = class_getInstanceMethod([NSString class], sel); 

    const char* const type = method_copyReturnType(method); 

    printf("%s : %s\n", NSStringFromSelector(sel).UTF8String, type); 

    free((void*)type); 
} 

int main(int argc, char *argv[]) { 
    @autoreleasepool { 

     test(@selector(init)); 
     test(@selector(superclass)); 
     test(@selector(isEqual:)); 
     test(@selector(length)); 

     return 0; 
    } 
} 

、あなたはその後、出発点としてこれを使用することができます:

typedef struct t_pair_alignof_sizeof { 
    size_t align; 
    size_t size; 
} t_pair_alignof_sizeof; 

static t_pair_alignof_sizeof MakeAlignOfSizeOf(size_t align, size_t size) { 
    t_pair_alignof_sizeof ret = {align, size}; 
    return ret; 
} 

static t_pair_alignof_sizeof test2(SEL sel) { 
    Method method = class_getInstanceMethod([NSString class], sel); 
    const char* const type = method_copyReturnType(method); 
    const size_t length = strlen(type); 

    if (1U == length) { 
     switch (type[0]) { 
      case '@' : 
       return MakeAlignOfSizeOf(__alignof__(id), sizeof(id)); 
      case '#' : 
       return MakeAlignOfSizeOf(__alignof__(Class), sizeof(Class)); 
      case 'c' : 
       return MakeAlignOfSizeOf(__alignof__(signed char), sizeof(signed char)); 
      ... 
+0

したがって、答えは:自分で実装することなくこれを行う方法はありません。正しい? –

+0

@Tilo私は実行時にいくつかばかげたことをしました。私が知っている無料の解決策はありませんが、サポートする必要があるタイプが分かっていれば、私の答えの解決策は簡単に実装できます。もちろん、より適切な回答が得られるかどうかを待つこともできます。 – justin

+0

@Tilo - このデモを追加しました – justin

5

私はあなたがNSGetSizeAndAlignmentを探していると信じています:

は、実際のサイズとの整列サイズを取得エンコードされた型。

const char * NSGetSizeAndAlignment (
    const char *typePtr, 
    NSUInteger *sizep, 
    NSUInteger *alignp 
);

議論
は、実際のサイズとtypePtrで表される第一のデータ・タイプの位置合わせサイズを取得し、typePtrにおける次のデータ・タイプの位置へのポインタを返します。

これは基本ランタイムの一部ではなく、おそらくあなたが見つからなかったFoundation関数です。

UPDATE:あなたが最初にあなたがCocotronを使用していることを言及しなかったが、それはそこにも利用可能です。 Cocotronの財団のNSObjCRuntime.mにあります。

明らかに、エンコーディング文字が変更される可能性はほとんどありませんが、独自のランタイムによって生成された文字列を常に正しく処理することができるため、独自のロールオーバーよりもはるかに優れています。

しかし何らかの理由で、メソッドのシグネチャ文字列(おそらくメモリ内のオフセットと関係がある)の数字要素を処理できません。 This improved version, by Mike Ashはこれを行います:

static const char *SizeAndAlignment(const char *str, NSUInteger *sizep, NSUInteger *alignp, int *len) 
{ 
    const char *out = NSGetSizeAndAlignment(str, sizep, alignp); 
    if(len) 
     *len = out - str; 
    while(isdigit(*out)) 
     out++; 
    return out; 
} 
+0

+1良い見つけよう、Josh – justin

+0

問題は、アップル製品にのみ存在するため、アップル財団への一般的なアクセス権がないことです。私が取り組んでいるプロジェクトは、ココトロン(財団の代替案)です。だから私はFoundationメソッドを使うことはできません。 –

+0

@Tilo:あなたが使っているフレームワークは、おそらくあなたの質問に含まれていたはずの非常に大きな状態です**。しかし、同じ機能がCococtronで利用可能です。私の編集を参照してください。 –

関連する問題