簡體   English   中英

在Objective C(Mac OS X)中檢測CPU架構(32位/ 64位)運行時

[英]Detect CPU Architecture (32-bit / 64-bit) runtime in Objective C (Mac OS X)

我正在擰一個Cocoa應用程序,它需要執行一些針對32位和64位優化的(控制台)應用程序。 因此,我想檢測運行應用程序的CPU架構,以便啟動正確的控制台應用程序。

簡而言之:如何檢測應用程序是否在64位操作系統上運行?

編輯:我知道Mach-O胖二進制文件,這不是我的問題。 我需要知道這一點,所以我可以啟動另一個非捆綁(控制台)應用程序。 一個針對x86進行了優化,另一個針對x64進行了優化。

有一種超級簡單的方法。 編譯可執行文件的兩個版本,一個用於32位,一個用於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

編輯:D'哦! 我沒有意識到你需要運行時檢查...通過sysctl -A的輸出,兩個變量看起來可能有用。 嘗試解析sysctl hw.optional.x86_64sysctl hw.cpu64bit_capable的輸出。 我沒有32位Mac來測試這個,但是在Core2Duo Mac上的Snow Leopard中這兩個都設置為1。

使用[[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;
}

您不必手動檢測它以實現該效果。 一個Mach-O可執行文件可以包含32位和64位英特爾機器的二進制文件,內核自動運行最合適的文件。 如果您正在使用XCode,則項目檢查器中有一個設置,您可以在其中設置要在單個通用二進制文件中使用的體系結構(ppc,i386,x86_64)。

此外,請記住,在OS X上,運行64位內核(使用Snow Leopard)並能夠運行64位用戶登陸應用程序是兩個正交的概念。 如果你有一台64位cpu的機器,即使內核以32位模式運行(使用Leopard或Snow Leopard),你也可以在64位模式下運行用戶域程序,只要所有的庫都可以。你鏈接的是64位。 因此,檢查操作系統是否具有64位功能並不是那么有用。

通常,您不需要能夠在運行時檢查您是64位還是32位。 如果您的主機應用程序(我稱之為啟動64位或32位工具的應用程序)是胖二進制文件,則編譯時檢查就足夠了。 因為它將被編譯兩次(一次用於胖二進制文件的32位部分,一次用於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位顯式啟動您的應用程序,請相信他們知道他們正在做什么。 無論如何,這是一個邊緣案例,為什么要為權力​​用戶打破錯誤的完美感。 如果您發現一個64位的錯誤,如果您可以告訴用戶解決方法是以32位方式啟動,您甚至可能會感到高興。

如果您的應用程序本身只有32位(例如帶有命令行幫助程序的Carbon GUI),您只需要進行真正的運行時檢查。 在這種情況下,host_processor_info或sysctl或類似的可能是你唯一的路由,如果由於一些奇怪的原因你不能只是將兩個可執行文件組合在一起。

如果您使用的是Snow Leopard,請使用NSRunningApplication的executableArchitecture。

否則,我會做以下事情:

-(BOOL) is64Bit
{
#if __LP64__
  return YES;
#else
  return NO;
#endif
}

以編程方式獲取具有CPU體系結構名稱的字符串:

#include <sys/types.h>
#include <sys/sysctl.h>

// Determine the machine name, e.g. "x86_64".
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0); // Get size of data to be returned.
char *name = malloc(size);
sysctlbyname("hw.machine", name, &size, NULL, 0);

// Do stuff...

free(name);

要在shell腳本中執行相同的操作:

set name=`sysctl -n hw.machine`

檢查操作系統版本的標准方法(因此其是否雪豹,一個64位操作系統)中詳細說明這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM