使用Python的ctypes将数组指针传递给具有struct返回类型的C函数

2024-04-23 06:29:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个C函数-

ERROR foo(int32_t* toptr, int64_t length) { 
    for (int32_t i = 0;  i < length;  i++) { 
        toptr[i] = i; 
    } 
    return bar(); 
}

ERRORbar定义为-

#define ERROR struct Error


struct __attribute__((visibility("default"))) Error {
    const char* x;
    int64_t hu;
};

inline struct Error
bar() {
 struct Error bla;
 bla.x = nullptr;
 bla.hu = 0;
 return bla;
};

如何使用ctypes表示此结构? 根据https://stackoverflow.com/a/38663141/4647107,我应该重新声明它,但我的struct的格式与该答案略有不同

我可以使用ctypes成功加载函数-

>>> import ctypes
>>> test = ctypes.CDLL("dummy.so")
>>> test.foo
<_FuncPtr object at 0x7f6cec73b7c0>

如果我将占位符返回类型分配给foo-

test.foo.restype = ctypes.c_bool

然后尝试使用它(基于https://stackoverflow.com/a/4145859/4647107)——

test.foo.argtypes = ctypes.POINTER(ctypes.c_int32), ctypes.c_int64
outarray = [1, 2, 3, 4, 5]
test.foo((ctypes.c_int32 * len(outarray))(*outarray), len(outarray))

我得到一个Segmentation fault (core dumped)错误


Tags: 函数testreturnfoobarerrorctypeslength
1条回答
网友
1楼 · 发布于 2024-04-23 06:29:23

struct Error未提供。下面是一个声明结构并使用它的示例

测试c:

#include <stdint.h>

typedef struct Error
{
    const char* x;
    int64_t hu;
} ERROR;

ERROR bar() {
    ERROR bla;
    bla.x = NULL;
    bla.hu = 5;
    return bla;
}

__declspec(dllexport)
ERROR foo(int32_t* toptr, int64_t length) {
    for (int32_t i = 0;  i < length;  i++) {
        toptr[i] = i;
    }
    return bar();
}

test.py:

from ctypes import *

class Error(Structure):
    _fields_ = [('x',c_char_p),
                ('hu',c_int64)]

dll = CDLL('./test')
dll.foo.argtypes = POINTER(c_int32),c_int64
dll.foo.restype = Error

outarray = (c_int32 * 5)()
err = dll.foo(outarray,len(outarray))
print(err.x)
print(err.hu)
print(list(outarray))

输出:

None
5
[0, 1, 2, 3, 4]

相关问题 更多 >