在32位Linux中使用ctypes返回结构体时出现段错误

4 投票
1 回答
1064 浏览
提问于 2025-04-17 07:16

我在一台32位的Linux机器上遇到了一个段错误(segfault),但在64位的Darwin或Linux上却无法重现这个问题。

这是C语言的代码:

typedef struct {
  void *ptr;
  } doodle;

doodle C_intpointerfunction(int *a)
{
  *a = 41;
  doodle foo;
  foo.ptr = a;
  return foo;
}

这个代码是用以下方式编译的:

gcc -c intpointerlibrary.c
gcc -shared intpointerlibrary.o -o libintpointerlib.so

这是Python的代码:

import numpy as N
from ctypes import *

_libintpointer = N.ctypeslib.load_library('libintpointerlib.so','.')

_libintpointer.C_intpointerfunction.restype = c_void_p
_libintpointer.C_intpointerfunction.argtypes = [POINTER(c_int)]
def P_intpointerfunction():
  lrc = c_int(0)
  print "lrc before (should be 0) = "+str(lrc.value)
  return_val = _libintpointer.C_intpointerfunction(byref(lrc))
  print "lrc after (should be 41) = "+str(lrc.value)
  return return_val

现在,当我调用这个函数时:

  rc = P_intpointerfunction()

我就会遇到段错误。我尝试创建一个Python类来包装在C语言那边创建的返回结构,结果还是一样。如果返回的是一个原生的ctypes类型(比如c_int),一切都正常。那么,这真的是32位Linux的问题吗,还是我还有什么没有考虑到的呢?谢谢!

1 个回答

5

我不太明白你为什么要把 restype = c_void_p 这样设置;

class DOODLE(Structure):
    _fields_ = [('ptr', c_void_p)]
_libintpointer.C_intpointerfunction.restype = DOODLE

在我这里,Linux x86-64上运行得很好。

撰写回答