Python 3 ctypes调用函数与返回的struct失败并出现segfault

时间:2018-06-15 14:02:58

标签: python c python-3.x ctypes

我试图运行一个返回包含多个int的结构的C函数(现在)。

我的C源代码如下:

struct my_struct {
    int i;
    int j;
} ;

extern "C" struct my_struct struct_test(){
    struct my_struct s;
    s.i = 2;
    s.j = 331;
    return s;
}

相应的Makefile是这样的:

CXX=/usr/bin/g++
PYTHON=/usr/bin/ipython3 --colors Linux

CXXFLAGS=-Wall -fPIC -O3 -c 
LDFLAGS=-Wall -shared -Wl,-soname,libfoo.so

TARGETS=mylib.so

all: mylib.so test

mylib.so: mylib.cpp
    $(CXX) $(CXXFLAGS) -o mylib.o mylib.cpp
    $(CXX) $(LDFLAGS) -o mylib.so mylib.o 

test: mylib.so
    $(PYTHON) ctypes_call_test.py

clean:
    rm -f $(TARGETS)

Python脚本在这里:

import ctypes

libname = './mylib.so'

class my_struct(ctypes.Structure):
    _fields_ = [
        ("i", ctypes.c_int),
        ("j", ctypes.c_int),
    ]
mylib = ctypes.cdll.LoadLibrary(libname)
mylib.struct_test.argtypes=[]
mylib.struct_test.restype=ctypes.POINTER(my_struct)
ret = mylib.struct_test();
print('got return value')
print(ret.contents.i, ret.contents.j)

当我运行Python脚本时,它会在print()语句后立即崩溃。任何想法为什么会发生这种情况?

1 个答案:

答案 0 :(得分:5)

您在结构中的返回值中指定了指针,而它本身就是结构。

将最后一行更改为:

mylib.struct_test.restype = my_struct  # <=== no more pointer
ret = mylib.struct_test();
print('got return value')
print(ret.i, ret.j)     # <=== remove "contents"

打印:

got return value
(2, 331)