从NSTask子进程强制Python以64模式运行



什么是从NSTask强制python以64模式运行的方法?

更新:根据Ned的建议,我尝试直接用目标c引用Python2.7,结果成功了。将@"/usr/bin/python"更改为@"/usr/bin/python2.7"。新代码位于问题的底部

我有一个64位系统。当从终端运行时,python以64位运行。当我从运行/usr/bin/uname-m的NSTask运行纯shell时,它会返回x86_64。

我尝试过使用arch,但运行shell的python仍然处于32位模式。

示例方法

-(void) runPython64BitScriptViaArchWithPath:(NSString*)path {
    NSTask* task = [[NSTask alloc] init];
    task.launchPath = @"/usr/bin/arch" ;
    task.arguments = [NSArray arrayWithObjects: @"-x86_64", @"/usr/bin/python", path, nil];
    [task setStandardInput:[NSPipe pipe]] ;
    NSPipe *stdOutPipe = nil;
    stdOutPipe = [NSPipe pipe];
    [task setStandardOutput:stdOutPipe];
    NSPipe* stdErrPipe = nil;
    stdErrPipe = [NSPipe pipe];
    [task setStandardError: stdErrPipe];
    NSLog(@"%@", [task arguments]) ;
    [task launch] ;
    NSData* data = [[stdOutPipe fileHandleForReading] readDataToEndOfFile];
    [task waitUntilExit];
    NSInteger exitCode = task.terminationStatus;
    if (exitCode != 0)
    {
        NSLog(@"Error!");
        NSData *error = [[stdErrPipe fileHandleForReading] readDataToEndOfFile] ;
        NSLog(@"Exit code : %ld", (long)exitCode) ;
        NSString *result = [[NSString alloc] initWithBytes: error.bytes length:error.length encoding: NSUTF8StringEncoding] ;
        NSLog(@"%@",result);
        [result release];
    } else {
        NSString *result = [[NSString alloc] initWithBytes: data.bytes length:data.length encoding: NSUTF8StringEncoding] ;
        NSLog(@"%@",result) ;
        [result release];
    }
    [task release] ;
}

一个从终端运行的python脚本示例

#!/usr/bin/env python
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'social_shields.settings'
try:
    import hosts.models
    shield = hosts.models.Shield.objects.all()[0]
    shield.active = True
    shield.save()
except Exception as exception:
    import struct
    print 'Bits : %s' % ( 8 * struct.calcsize("P"))
    print exception

示例日志

2013-07-04 16:10:31.600 socialshield[88688:303] onShieldDown
2013-07-04 16:10:31.607 socialshield[88688:303] x86_64
2013-07-04 16:10:31.607 socialshield[88688:303] (
    "-x86_64",
    "/usr/bin/python",
    "/source/social_shields/social_shields/shield_down.py"
)
2013-07-04 16:10:31.933 socialshield[88688:303] Bits : 32
Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-packages/_mysql.so, 2): no suitable image found.  Did find:
    /Library/Python/2.7/site-packages/_mysql.so: mach-o, but wrong architecture

应用Ned的建议后工作的新代码:-)

-(void) runPython64BitScriptViaArchWithPath:(NSString*)path {
    NSTask* task = [[NSTask alloc] init];
    task.launchPath = @"/usr/bin/arch" ;
    task.arguments = [NSArray arrayWithObjects: @"-x86_64", @"/usr/bin/python2.7", path, nil];
    [task setStandardInput:[NSPipe pipe]] ;
    NSPipe *stdOutPipe = nil;
    stdOutPipe = [NSPipe pipe];
    [task setStandardOutput:stdOutPipe];
    NSPipe* stdErrPipe = nil;
    stdErrPipe = [NSPipe pipe];
    [task setStandardError: stdErrPipe];
    NSLog(@"%@", [task arguments]) ;
    [task launch] ;
    NSData* data = [[stdOutPipe fileHandleForReading] readDataToEndOfFile];
    [task waitUntilExit];
    NSInteger exitCode = task.terminationStatus;
    if (exitCode != 0)
    {
        NSLog(@"Error!");
        NSData *error = [[stdErrPipe fileHandleForReading] readDataToEndOfFile] ;
        NSLog(@"Exit code : %ld", (long)exitCode) ;
        NSString *result = [[NSString alloc] initWithBytes: error.bytes length:error.length encoding: NSUTF8StringEncoding] ;
        NSLog(@"%@",result);
        [result release];
    } else {
        NSString *result = [[NSString alloc] initWithBytes: data.bytes length:data.length encoding: NSUTF8StringEncoding] ;
        NSLog(@"%@",result) ;
        [result release];
    }
    [task release] ;
}

我假设您已经验证了/Library/Python/2.7/site-packages/_mysql.so是64位的,并且在这两种情况下都使用了相同的Python。在OSX10.6及更高版本的系统上,/usr/bin/python实际上是一个包装器可执行文件,用于确定运行哪种版本的Python和哪种体系结构(32位或64位);详见man 1 python。尝试直接执行/usr/bin/python2.7。它应该默认为64位。您还可以使用以下文档测试来检查Python是以32位模式还是64位模式运行:

import sys; print(sys.maxsize > 2**32)

最新更新