使用标准C在Mac OS X中获取操作系统版本

我试图在C中以编程方式获得Mac OS X的版本。在搜索了一段时间之后我尝试了这段代码:

#include  int GetOS() { SInt32 majorVersion,minorVersion,bugFixVersion; Gestalt(gestaltSystemVersionMajor, &majorVersion); Gestalt(gestaltSystemVersionMinor, &minorVersion); Gestalt(gestaltSystemVersionBugFix, &bugFixVersion); printf("Running on Mac OS X %d.%d.%d\n",majorVersion,minorVersion,bugFixVersion); return 0; } 

XCode返回LD错误:

Undefined symbols for architecture x86_64: "_Gestalt", referenced from: _GetOS in main.o

我错过了什么? 你怎么做到这一点?

我也发现了这个片段

 [[NSProcessInfo processInfo] operatingSystemVersionString] 

但我不知道怎么用C写的。

您是否CoreServices适当的框架传递给GCC以启用CoreServices

 % gcc -framework CoreServices -o getos main.c 

下面的代码应该在可预见的将来用于确定当前版本的Mac Os X.

 /* McUsr put this together, and into public domain, without any guarrantees about anything, but the statement that it works for me. */ #if 1 == 1 #define TESTING #endif #include  #include  #include  #include  #include  #include  struct osver { int minor; int sub; } ; typedef struct osver osxver ; void macosx_ver(char *darwinversion, osxver *osxversion ) ; char *osversionString(void) ; #ifdef TESTING int main( int argc, char *argv[] ) { osxver foundver; char *osverstr= NULL ; osverstr=osversionString() ; macosx_ver(osverstr, &foundver ) ; printf("Mac os x version = 10.%d.%d\n",foundver.minor,foundver.sub ); free(osverstr); return 0; } #endif char *osversionString(void) { int mib[2]; size_t len; char *kernelVersion=NULL; mib[0] = CTL_KERN; mib[1] = KERN_OSRELEASE; if (sysctl(mib, 2, NULL, &len, NULL, 0) < 0 ) { fprintf(stderr,"%s: Error during sysctl probe call!\n",__PRETTY_FUNCTION__ ); fflush(stdout); exit(4) ; } kernelVersion = malloc(len ); if (kernelVersion == NULL ) { fprintf(stderr,"%s: Error during malloc!\n",__PRETTY_FUNCTION__ ); fflush(stdout); exit(4) ; } if (sysctl(mib, 2, kernelVersion, &len, NULL, 0) < 0 ) { fprintf(stderr,"%s: Error during sysctl get verstring call!\n",__PRETTY_FUNCTION__ ); fflush(stdout); exit(4) ; } return kernelVersion ; } void macosx_ver(char *darwinversion, osxver *osxversion ) { /* From the book Mac Os X and IOS Internals: In version 10.1.1, Darwin (the core OS) was renumbered from v1.4.1 to 5.1, and since then has followed the OS X numbers consistently by being four numbers ahead of the minor version, and aligning its own minor with the sub-version. */ char firstelm[2]= {0,0},secElm[2]={0,0}; if (strlen(darwinversion) < 5 ) { fprintf(stderr,"%s: %s Can't possibly be a version string. Exiting\n",__PRETTY_FUNCTION__,darwinversion); fflush(stdout); exit(2); } char *s=darwinversion,*t=firstelm,*curdot=strchr(darwinversion,'.' ); while ( s != curdot ) *t++ = *s++; t=secElm ; curdot=strchr(++s,'.' ); while ( s != curdot ) *t++ = *s++; int maj=0, min=0; maj= (int)strtol(firstelm, (char **)NULL, 10); if ( maj == 0 && errno == EINVAL ) { fprintf(stderr,"%s Error during conversion of version string\n",__PRETTY_FUNCTION__); fflush(stdout); exit(4); } min=(int)strtol(secElm, (char **)NULL, 10); if ( min == 0 && errno == EINVAL ) { fprintf(stderr,"%s: Error during conversion of version string\n",__PRETTY_FUNCTION__); fflush(stdout); exit(4); } osxversion->minor=maj-4; osxversion->sub=min; } 

这里有一个“工作量少”,足够用于家庭项目(静态分配缓冲区,忽略错误)。 适用于OS X 10.11.1。

 #include  /*! @brief Returns one component of the OS version @param component 1=major, 2=minor, 3=bugfix */ int GetOSVersionComponent(int component) { char cmd[64] ; sprintf( cmd, "sw_vers -productVersion | awk -F '.' '{print $%d}'", component ) ; FILE* stdoutFile = popen(cmd, "r") ; int answer = 0 ; if (stdoutFile) { char buff[16] ; char *stdout = fgets(buff, sizeof(buff), stdoutFile) ; pclose(stdoutFile) ; sscanf(stdout, "%d", &answer) ; } return answer ; } int main(int argc, const char * argv[]) { printf( "Your OS version is: %d.%d.%d\n", GetOSVersionComponent(1), GetOSVersionComponent(2), GetOSVersionComponent(3) ) ; return 0 ; }