在 Python 中使用 ctypes.CDLL 调用 c 函数时,该函数总是将 0 作为参数传递
When calling a c function using ctypes.CDLL in Python, the function always gets 0 passed along as argument
我正在尝试调用的 c 函数:
#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'
注意输出如何为 0。即使我将参数更改为 4 以外的其他值,输出始终为 0。
如果我尝试将 soFile.main(4)
更改为具有两个参数的东西,例如 soFile.main(2, 4)
,我会得到
:!python test.py "collatz-loop"
shell returned 139
为什么会这样,我该如何解决?
- 顺便说一下,我是 c 的新手,但对 Java 非常熟悉。它们在语法上看起来非常相似。
- 是的,我确实记得在 运行 .py 文件之前 save/write python 和 c 文件。
评论线程的 TLDR:
你应该把它分成 2 个函数,main
和 collatz
(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
以避免在未传递任何参数时发生越界读取。
我正在尝试调用的 c 函数:
#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'
注意输出如何为 0。即使我将参数更改为 4 以外的其他值,输出始终为 0。
如果我尝试将 soFile.main(4)
更改为具有两个参数的东西,例如 soFile.main(2, 4)
,我会得到
:!python test.py "collatz-loop"
shell returned 139
为什么会这样,我该如何解决?
- 顺便说一下,我是 c 的新手,但对 Java 非常熟悉。它们在语法上看起来非常相似。
- 是的,我确实记得在 运行 .py 文件之前 save/write python 和 c 文件。
评论线程的 TLDR:
你应该把它分成 2 个函数,main
和 collatz
(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
以避免在未传递任何参数时发生越界读取。