The c function I am trying to call:
#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; }
My python code that attempts to call it with parameter 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) # <----------
In vim I run the following:
:!python test.py "collatz-loop" you typed: collatz-loop main(0) Collatz(0) is '0'
Notice how the output is 0. Even if I change the parameter to something other than 4, the output is always 0.
If I try to change soFile.main(4)
to something with, say, two parameters, like soFile.main(2, 4)
, I get
:!python test.py "collatz-loop" shell returned 139
Why is this happening, and how do I fix it?
- I am new to c by the way, though very familiar with Java. They seem very alike syntactically.
- Yes, I did remember to save/write the python and c file before running the .py file.
Answer
TLDR for comment thread:
You should split it into 2 funcs, main
and collatz
(int collatz(long long n)
) and make main just pass atoll(argv[1])
to collatz, so you can run it normally as an executable and also from your python script file as a shared library. You also need to set the argtype in ctypes to long long(I think it defaults to 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)
Note: Not directly related to this issue, but you should check to make sure argc > 2
in your C code to avoid an out of bounds read if no args are passed.