簡體   English   中英

When calling a c function using ctypes.CDLL in Python, the function always gets 0 passed along as argument

[英]When calling a c function using ctypes.CDLL in Python, the function always gets 0 passed along as argument

c function 我想打電話:

#include <stdio.h>    
#include <stdlib.h>    
  
int main(int argc, char *argv[]){       
    long long int n = atoll(argv[1]);    
    printf("main(%lld)\n", n);    
    int m = 0;         
    while (n > 1) {           
        m++;                  
        if (n % 2 == 0) {   // even    
            printf("%lld = %lld/2 \n", n/2, n);    
            n = n/2;    
        }    
        else {    
            printf("%lld = 3*%lld+1 \n", 3*n+1, n);    
            n = 3*n + 1;    
        }    
    }        
    printf("Collatz(%lld) is '%d'\n", n,m);    
    return m;    
}    

我的 python 代碼嘗試使用參數 4 調用它

from ctypes import *    
import os, sys                                                                    
                                                                                    
print("you typed:", sys.argv[1])                                                  
                                                                                    
filename = sys.argv[1].split(".")[0]                                              
                                                                                    
os.system(f"gcc -c -fPIC {filename}.c -o {filename}.o && gcc {filename}.o " \     
           f"-shared -o {filename}.so")                                           
       
soFile = CDLL(os.getcwd() + "/" + filename + ".so")    
       

soFile.main(4)       # <----------

在 vim 中,我運行以下命令:

:!python test.py "collatz-loop"                                                
you typed: collatz-loop
main(0)
Collatz(0) is '0'

注意 output 如何為 0。即使我將參數更改為 4 以外的值,output 始終為 0。

如果我嘗試將soFile.main(4)更改為具有兩個參數的東西,例如soFile.main(2, 4) ,我會得到

:!python test.py "collatz-loop"

shell returned 139

為什么會發生這種情況,我該如何解決?

  • 順便說一句,我是 c 的新手,雖然對 Java 非常熟悉。 它們在語法上看起來非常相似。
  • 是的,我確實記得在運行 .py 文件之前保存/寫入 python 和 c 文件。

評論線程的 TLDR:您應該將其拆分為 2 個函數, maincollatz ( int collatz(long long n) ),並使 main 只需將atoll(argv[1])傳遞給 collatz,因此您可以將其作為可執行文件正常運行,並且也來自您的 python 腳本文件作為共享庫。 您還需要將 ctypes 中的 argtype 設置為 long long(我認為它默認為 int)。

C:

#include <stdio.h>
#include <stdlib.h>

int collatz(long long n){
    int m = 0;
    while (n > 1) {
        m++;
        if (n % 2 == 0) {   // even
            printf("%lld = %lld/2 \n", n/2, n);
            n = n/2;
        }
        else {
            printf("%lld = 3*%lld+1 \n", 3*n+1, n);
            n = 3*n + 1;
        }
    }
    printf("Collatz(%lld) is '%d'\n", n,m);
    return m;
}

int main(int argc, char *argv[]){
    long long int n = atoll(argv[1]);
    printf("main(%lld)\n", n);
    collatz(n);
}

Python:

from ctypes import *
import os, sys

print("you typed:", sys.argv[1])

filename = sys.argv[1].split(".")[0]

os.system(f"gcc -c -fPIC {filename}.c -o {filename}.o && gcc {filename}.o " \
           f"-shared -o {filename}.so")

soFile = CDLL(os.getcwd() + "/" + filename + ".so")


soFile.collatz.argtypes = [c_longlong]
soFile.collatz(4)

注意:與此問題沒有直接關系,但您應該檢查以確保 C 代碼中的argc > 2以避免在沒有傳遞 args 時讀取越界。

暫無
暫無

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

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