4

私はctypesをいじっています...次のCコードがあります

編集:これを理解しようとしている理由は、このブログ投稿をより正確にするためです

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;
}

次のコマンドを使用してコンパイルします(OSX上)

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

Pythonで同じ機能を実装しました:

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

次に、インタラクティブ シェルで両方を実行します。

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

…そして数字が一致しません。これはなぜでしょうか?

unsigned long longCコードのすべての変数を効果なしで使用しようとしました(同じ出力)。

4

1 に答える 1

6

longは 32 ビット型であるため、C コードは単純にオーバーフローします。

Python はそうではありません。pysumrangeあなたに正しい答えを与えます。

ctypesあなたがそれを言わない限り、関数の戻り値の型がであることを知りませんunsigned long long。Python 標準ライブラリのドキュメントで戻り値の型を参照してください。それは言います:

デフォルトでは、関数は Cint型を返すと想定されています。restype関数オブジェクトの属性を設定することにより、他の戻り値の型を指定できます。

したがって、おそらく、関数を呼び出す直前にこれを行うとうまくいくでしょう:

sumrange.sumrange.restype = ctypes.c_ulonglong
于 2012-09-12T19:06:48.237 に答える