从ctypes访问大内存缓冲区时出现段错误

时间:2019-05-06 05:10:36

标签: python ctypes

访问Python中的内存时出现“分段错误(核心转储)错误”错误,该错误最初是在共享库中分配的。

返回内存的函数声明为:

    extern "C" double *get_sound_data(int desc);
    extern "C" long long get_sound_data_size(int desc);

Python代码是:

from ctypes import *
cdll.LoadLibrary("libsomelib.so")
_lib = CDLL("libsomelib.so")

size = _lib.get_sound_data_size(desc)
data = _lib.get_sound_data(desc)
data = cast(data, POINTER(c_double))
arr = []
for i in range(size):
    arr.append(data[i])

对于小型缓冲区(例如10k项),它可以工作,但是当库返回几兆字节的首次访问尝试时,即Python段错误中的data [0]。

我看过此页面,它看起来与https://bugs.python.org/issue13096

类似

我在Python 2.7.12和3.5.2中遇到相同的错误,操作系统是Linux。

1 个答案:

答案 0 :(得分:1)

您不能只假装默认的返回类型就可以,并尝试将无用的结果强制转换为应有的类型。 (实际上,Python可能永远都不应该为此使用默认值,但是更改它为时已晚。)默认值是假定C函数返回C int,并且不能保证C int与a的大小相同。指针;这些天,可能不是。

您需要实际设置argtypesrestype才能通过ctypes安全地使用您的功能。

get_sound_data = _lib.get_sound_data
get_sound_data_size = _lib.get_sound_data_size

get_sound_data.argtypes = (ctypes.c_int,)
get_sound_data.restype = ctypes.POINTER(ctypes.c_double)

get_sound_data_size.argtypes = (ctypes.c_int,)
get_sound_data_size.restype = ctypes.c_longlong

# Now use the functions