2015-06-22 55 views
3

有幾種調用C++可執行程序的方法。例如,我們可以使用python腳本可以知道Android環境中C++主函數的返回值

def run_exe_return_code(run_cmd): 
     process=subprocess.Popen(run_cmd,stdout=subprocess.PIPE,shell=True) 
     (output,err)=process.communicate() 
     exit_code = process.wait() 
     print output 
     print err 
     print exit_code 
     return exit_code 

處理一個C++可執行程序:run_exe_return_code('abc')abc由以下的C創建++代碼:

int main() 
{ 
     return 1; 
} 

在上述代碼中,程序的返回值是1,如果我們在Linux中運行這個Python腳本,我們總能看到Python腳本的返回值爲1.但是,在Android環境中,上面的python腳本中的返回出口代碼似乎是0,這意味着成功。有沒有一種解決方案,Python腳本可以知道Android環境中主函數的返回值?

順便說一下,在Android環境下,我使用adb shell abc而不是abc來運行該程序。

+1

你能描述一個這不起作用的真實例子嗎?是什麼讓你覺得0不是正確答案? –

+0

@ReutSharabani測試它非常簡單。在main()函數中,你什麼都不做,只能返回1.然後你只需運行run_exe_return_code python函數,並且exit_code爲0.然後,如果你將main()函數中的返回值更改爲0,並運行一次python腳本再次,你會發現exit_code仍爲0. – feelfree

+0

@feelfree那麼爲什麼不使用'int main(){return 1;}'來創建一個*完整的例子呢?它可以避免混淆,更重要的是可以立即編譯。 – luk32

回答

3

於Android的問題,您可以使用fb-adb其中「傳播計劃退出狀態,而不是總與狀態0退出」(首選),或使用本workaround(hackish的...不推薦用於生產用途):

def run_exe_return_code(run_cmd): 
     process=subprocess.Popen(run_cmd + '; echo $?',stdout=subprocess.PIPE,shell=True) 
     (output,err)=process.communicate() 
     exit_code = process.wait() 
     print output 
     print err 
     print exit_code 
     return exit_code 

請注意,最後一個進程的代碼是echo -ed所以從輸出中得到它,而不是從adb的exit_code得到它。

$?返回最後的退出代碼。所以打印它可以讓你從python訪問它。


至於你原來的問題:

我不能重現此。下面是一個簡單的例子:

.c文件的內容:

[email protected]:~/pyh$ cat c.c 
int main() { 
    return 1; 
} 

編譯(到a.out默認...):

內容的
[email protected]:~/pyh$ gcc c.c 

.py文件:

[email protected]:~/pyh$ cat tstc.py 
#!/usr/bin/env python 

import subprocess 

def run_exe_return_code(run_cmd): 
    process=subprocess.Popen(run_cmd,stdout=subprocess.PIPE) 
    (output,err)=process.communicate() 
    exit_code = process.wait() 
    print output 
    print err 
    print exit_code 

run_exe_return_code('./a.out') 

測試:

[email protected]:~/pyh$ ./tstc.py 

None 
1 

exit_code1如預期。

請注意,返回值始終是一個整數。您可能需要使用以下輸出:subprocess.check_output

使用參數運行命令並將其輸出作爲字節字符串返回。

例子:

>>> subprocess.check_output(["echo", "Hello World!"]) 
'Hello World!\n' 

注:如果返回值是1,這標誌着一個錯誤,一個CalledProcessError將引發異常(這通常是一件好事,因爲你可以對其進行響應)。

+1

如果退出狀態爲非零,則check_output將引發CalledProcessError,因此您必須捕獲該異常 –

+0

這是在他正在尋找寫入'stdout'的內容的假設下編寫的,但感謝您的評論。 –

+1

是的,但如果代碼返回1,您將看不到輸出,程序將出錯。你也不需要shell = True –

0

我想你可以嘗試commands.getstatusoutput,像這樣:

import commands

status, result = commands.getstatusoutput(run_cmd)

print result

+0

謝謝,我已重新編輯該問題,因爲我發現這只是Android中的一個問題。 – feelfree

0

看到這個答案:https://stackoverflow.com/a/5631819/902846。它適應你的榜樣,它應該是這樣的:

def run_exe_return_code(run_cmd): 
    process = subprocess.Popen(run_cmd, stdout=subprocess.PIPE, shell=True) 
    (output, err) = process.communicate() 
    process.wait() 
    print output 
    print err 
    print process.returncode 
    return process.returncode 

簡短的總結是,你可以使用Popen.waitPopen.poll,或Popen.communicate酌情導致返回代碼進行更新,然後檢查與返回代碼之後再加上Popen.returncode

另請參閱Python文檔的POPEN:https://docs.python.org/2/library/subprocess.html

+0

謝謝,我已重新編輯該問題,因爲我發現這只是Android中的一個問題。 – feelfree

0

是的,你可以! 您所提交的代碼的簡單的版本是:

import subprocess 
exit_code=subprocess.call('./a.out')` 
print exit_code 

與./a.out程序從編譯:

int main(){ 
    return 3; 
} 

測試:

python testRun.py 
3 

啊,和記shell = True可能是安全隱患。 https://docs.python.org/2/library/subprocess.html

def run_exe_return_code(run_cmd): 
    process=subprocess.Popen(run_cmd,stdout=subprocess.PIPE,shell=True) 
+0

謝謝,我重新編輯了這個問題。 – feelfree

+0

您正在使用哪個版本的python? 顯然,Android上的子進程端口是一個問題。 https://bugs.python.org/issue16255 https://code.google.com/p/python-for-android/source/browse/python3-alpha/python3-src/Lib/subprocess.py?r = b3c1049b5eadd74a307f917b3703ab6911165e4e –

0
def run_exe_android_return_code(run_cmd): 
    #adb shell '{your command here} > /dev/null 2>&1; echo $?' 
    process=subprocess.Popen(run_cmd,stdout=subprocess.PIPE,shell=True) 
    (output,err)=process.communicate() 
    pos1 = output.rfind('\n') 
    output = output[:pos1-1] 
    pos2 = output.rfind('\n') 
    output = output[pos2+1:] 
    print output 
    return output 

這是用來檢查運行在Android上的可執行文件的返回值的Python腳本。

def run_android_executable(full_path,executable): 
    executable = full_path+'/'+executable 
    run_cmd = 'adb shell \'LD_LIBRARY_PATH='+full_path+':$LD_LIBRARY_PATH '+executable+'; echo $?\'' 
    print run_cmd 
    error_code=run_exe_android_return_code(run_cmd) 
    print 'the error code is' 
    print error_code 
    if(error_code=='1'): 
     print 'the executable returns error' 
    else: 
     print 'the exectuable runs smoothly' 

這是用來運行可執行文件的腳本。這與Reut Sharabani的回答有點不同,並且它很有效。