2

I want to do some Python multithreading and bypass the GIL using ctypes.

I wrote some C code, test.c:

long long sum_range(long high)
{
  long i;
  long long s = 0LL;
 
  for (i = 0L; i < high; i++)
      s += (long long)i;

  return s;
}

Compile and link using

gcc -O3 -g -fPIC -c -o test.o test.c
ld -shared -o libtest.so test.o

Call it from a Python 3 script:

import ctypes
import os

testlib = ctypes.cdll.LoadLibrary(os.getcwd()+"/libtest.so")

sum_range = testlib.sum_range
sum_range.argtypes = [ctypes.c_long]
sum_range.restypes = ctypes.c_longlong

iterations=100000

print("sum_range(iterations) = {}".format(sum_range(iterations)))

This gives

sum_range(iterations) = 704982704

Instead of 4999950000. What is wrong here?

PS Adding a printf to the C code shows that the correct value of 4999950000 is being returned to the Python script.

PPS The correct value is printed when iterations is e.g. ten times smaller, so 10000.

PPPS A similar question was raised earlier but setting restypes apparently does not fix the problem.

Alex van Houten
  • 308
  • 3
  • 17
  • Should that be `sum_range.restype` instead of `sum_range.restypes`? I'm not familiar with ctypes at all, but the answer you linked to uses `restype` and not `restypes`. – Kevin Nov 19 '20 at 14:46
  • That's it! Thanks. It should be restype (singular) and argtypes is plural. Does not make complete sense to me since a C library can return multiple values. Also weird that no error is raised when using restypes (plural). – Alex van Houten Nov 19 '20 at 14:51
  • A function in C or Python can only return a single value. That might be a struct in C or a tuple/list in Python, but it's still a single value. No error was raised because the `sum_range` object probably has a `__dict__` that lets you set arbitrary attributes (this is by default for python types). Search for "\_\_dict\_\_" on the [data model page](https://docs.python.org/3/reference/datamodel.html) – Kevin Nov 19 '20 at 14:57
  • Duplicate of https://stackoverflow.com/questions/58610333/c-function-called-from-python-via-ctypes-returns-incorrect-value. – CristiFati Nov 21 '20 at 08:35

0 Answers0