4

I am toying with ctypes… I have the following C code

Edit: The reason I'm trying to figure this out is to make this blog post more correct

sumrange.c

#include <stdio.h>

long sumrange(long);

long sumrange(long arg)
{
    long i, x;
    x = 0L;

    for (i = 0L; i < arg; i++) {
        x = x + i;
    }
    return x;
}

which I compile using the following command (on OSX)

$ gcc -shared -Wl,-install_name,sumrange.so -o ./sumrange.so -fPIC ./sumrange.c

I've implemented the same function in python:

pysumrange = lambda arg: sum(xrange(arg))

Then I run both at the interactive shell:

>>> import ctypes
>>> sumrange = ctypes.CDLL('./sumrange.so')
>>> pysumrange = lambda arg: sum(xrange(arg))
>>> print sumrange.sumrange(10**8), pysumrange(10**8)
... 887459712 4999999950000000

…and the numbers don't match. Why would this be?

I tried using unsigned long long for all the variables in the C code with no effect (same output).

2

1 Answer 1

6

long is a 32-bit type, so the C code simply overflows.

Python doesn’t; pysumrange gives you the correct answer.

ctypes doesn’t know that the function’s return type is unsigned long long unless you tell it. See return types in the Python standard library documentation. It says:

By default functions are assumed to return the C int type. Other return types can be specified by setting the restype attribute of the function object.

So perhaps doing this, just before calling the function, will work for you:

sumrange.sumrange.restype = ctypes.c_ulonglong
Sign up to request clarification or add additional context in comments.

1 Comment

It is good practice to also set the argtypes for a ctypes function. sumrange.sumrange.argtypes = [ctypes.c_long]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.