1

MacOSX 10.8.2 と最新の xcode およびストック python インタープリターを使用して、Mac で開発しています。

ここに私が入れたいくつかのコードがありますfails.cpp

#include <iostream>

using namespace std;

extern "C" {

void mysort(long *data, long data2) {
    cout << hex << *data << ' ' << data2 << endl;
}

}

これは、私が入れたpythonから呼び出すためのコードですfails.py

import ctypes

sort_dll = ctypes.CDLL("fails.dylib")
mysort = ctypes.CFUNCTYPE(None, ctypes.POINTER(ctypes.c_long), ctypes.c_long)(sort_dll.mysort)

a = ctypes.c_long(0x987654321)
mysort(ctypes.byref(a), 0x123456789)

私はコンパイルして実行します

c++ -arch x86_64 -o fails.o -c fails.cpp && g++ -o fails.dylib -dynamiclib fails.o && python fails.py

結果は次のとおりです。

987654321 23456789

値渡しされる 64 ビット整数が 32 ビットに切り捨てられるのはなぜですか? 驚いたことに、64 ビット long へのポインターは切り捨てられません。

4

1 に答える 1

1

Python ctypes ライブラリが c_long のサイズを 32 ビットと判断したためだと思われます。ドキュメントにはいくつかのヒントがあります:

C signed int データ型を表します。コンストラクターは、オプションの整数初期化子を受け入れます。オーバーフロー チェックは行われません。sizeof(int) == sizeof(long) のプラットフォームでは、 c_long のエイリアスです

このコードは、c_long が実際にどのくらい大きいかを示します。

import ctypes
print ctypes.sizeof(ctypes.c_long())

ctypes はポインター自体をマーシャリングするだけでよいため、ポインターが参照する値は切り捨てられません。ポインターが切り捨てられている可能性がありますが、上位ビットはすべてゼロであるため問題ありません。ctypes.POINTER が 64 ビットであると ctypes が判断した可能性もあります。上記の例を少し変更することで確認できます。

于 2012-11-16T02:42:04.120 に答える