4

私は現在、32 ビットと 64 ビットに最適化された (コンソール) アプリケーションを実行する必要があるCocoaアプリケーションを作成しています。このため、アプリケーションが実行されている CPU アーキテクチャを検出して、正しいコンソール アプリケーションを起動できるようにしたいと考えています。

要するに、アプリケーションが 64 ビット OS で実行されているかどうかを検出するにはどうすればよいですか?

編集: Mach-Oファット バイナリについては知っていますが、それは私の質問ではありませんでした。バンドルされていない別の (コンソール) アプリケーションを起動できるように、これを知る必要があります。1 つはx86用に最適化され、もう 1 つはx64用に最適化されています。

4

7 に答える 7

11

超簡単な方法があります。実行可能ファイルの 2 つのバージョン (1 つは 32 ビット用、もう 1 つは 64 ビット用) をコンパイルし、それらを lipo で結合します。そうすれば、正しいバージョンが常に実行されます。

gcc -lobjc somefile.m -o somefile -m32 -march=i686
gcc -lobjc somefile.m -o somefile2 -m64 -march=x86_64
lipo -create -arch i686 somefile -arch x86_64 somefile2 -output somefileUniversal

編集:または、最初にユニバーサルバイナリをコンパイルするだけですgcc -arch i686 -arch x86_64

OPのコメントに応えて:

if(sizeof(int*) == 4)
    //system is 32-bit
else if(sizeof(int*) == 8)
    //system is 64-bit

編集:ああ!実行時チェックが必要だとは思いませんでした... の出力をsysctl -A見ると、2 つの変数が役立つ可能性があります。sysctl hw.optional.x86_64との出力を解析してみてくださいsysctl hw.cpu64bit_capable。これをテストするための 32 ビット Mac はありませんが、Core2Duo Mac の Snow Leopard では両方とも 1 に設定されています。

于 2010-01-01T16:56:13.107 に答える
8

[[NSRunningApplication currentApplication] executableArchitecture]次の定数のいずれかを返すを使用します。

  • NSBundleExecutableArchitectureI386
  • NSBundleExecutableArchitectureX86_64
  • NSBundleExecutableArchitecturePPC
  • NSBundleExecutableArchitecturePPC64

例えば:

switch ([[NSRunningApplication currentApplication] executableArchitecture]) {
  case NSBundleExecutableArchitectureI386:
    // TODO: i386
    break;

  case NSBundleExecutableArchitectureX86_64:
    // TODO: x86_64
    break;

  case NSBundleExecutableArchitecturePPC:
    // TODO: ppc
    break;

  case NSBundleExecutableArchitecturePPC64:
    // TODO: ppc64
    break;

  default:
    // TODO: unknown arch
    break;
}
于 2010-10-01T10:05:47.227 に答える
3

通常、実行時に 64 ビットか 32 ビットかを確認できる必要はありません。ホスト アプリケーション (64 ビットまたは 32 ビット ツールを起動するアプリと呼びます) がファット バイナリである場合、コンパイル時のチェックで十分です。これは 2 回コンパイルされ (1 回はファット バイナリの 32 ビット部分用、もう 1 回は 64 ビット部分用)、システムによって正しいものが起動されるため、適切な起動コードでコンパイルするだけです。書き込みます。お気に入り

#if __LP64__
    NSString    *vExecutablePath = [[NSBundle mainBundle] pathForResource: @"tool64" ofType: @""];
#else
    NSString    *vExecutablePath = [[NSBundle mainBundle] pathForResource: @"tool32" ofType: @""];
#endif
[NSTask launchedTaskWithLaunchPath: vExecutableName ...];

ユーザーがなんらかの方法で 64 ビット Mac で 32 ビットのアプリを明示的に起動した場合は、ユーザーが何をしているかを知っていると信頼してください。いずれにせよ、これは特殊なケースであり、パワー ユーザーが間違った完璧な感覚から抜け出す理由です。回避策が 32 ビットとして起動されることをユーザーに伝えることができれば、64 ビットのみのバグを発見した場合でも、自分自身が喜ぶかもしれません。

アプリ自体が 32 ビットのみの場合 (例: コマンドライン ヘルパーを使用した Carbon GUI) は、実際のランタイム チェックのみが必要です。その場合、何らかの奇妙な理由で 2 つの実行可能ファイルを一緒に lipo できない場合は、おそらく host_processor_info または sysctl などを使用するしかありません。

于 2010-01-02T16:41:41.293 に答える
3

その効果を得るために手動で検出する必要はありません。1 つの Mach-O 実行可能ファイルに 32 ビットと 64 ビットの Intel マシンの両方のバイナリを含めることができ、カーネルは最も適切なものを自動的に実行します。XCode を使用している場合は、プロジェクト インスペクターに、単一のユニバーサル バイナリに含めるアーキテクチャ (ppc、i386、x86_64) を設定できる設定があります。

また、OS X では、64 ビット カーネル (Snow Leopard を使用) を実行することと、64 ビットのユーザー ランド アプリを実行できることは、2 つの直交する概念であることを覚えておいてください。64 ビット CPU のマシンを使用している場合、カーネルが 32 ビット モード (Leopard または Snow Leopard を使用) で実行されている場合でも、すべてのライブラリがインストールされている限り、ユーザーランド プログラムを 64 ビット モードで実行できます。とリンクすると、64 ビットで使用できます。そのため、OS が 64 ビットに対応しているかどうかを確認することはあまり役に立ちません。

于 2010-01-01T16:56:34.810 に答える
2

Snow Leopard を使用している場合は、NSRunningApplication の executableArchitecture を使用します。

それ以外の場合は、次のようにします。

-(BOOL) is64Bit
{
#if __LP64__
  return YES;
#else
  return NO;
#endif
}
于 2010-01-01T16:57:57.097 に答える
0

OS のバージョン (つまり、64 ビット OS である Snow Leopard かどうか) を確認する標準的な方法については、こちらで詳しく説明しています。

于 2010-01-01T16:48:57.163 に答える