gpt4 book ai didi

python - 从库返回的 ctypes 结构

转载 作者:太空宇宙 更新时间:2023-11-03 23:44:10 25 4
gpt4 key购买 nike

给定一个简单的 C 文件:

#include <stdio.h>

typedef struct point {
int x;
int y;
} POINT;

POINT get_point()
{
POINT p = {1, 2};
return p;
}

我有一个简单的 python 文件:

from ctypes import *
import os

lib_name = '/testlib.so'
test_lib = CDLL(os.getcwd() + lib_name)

class POINT(Structure):
_fields_ = [('x', c_int),
('y', c_int)]

# Sets p1 to the integer 1
p1 = test_lib.get_point()
# Sets p2 to the struct POINT with values {1, 0}
p2 = POINT(test_lib.get_point())

如何将我的返回值设置为结构 POINT,值为 {1, 2}

最佳答案

你问的是你的例子中唯一的问题。只是回答你首先问的问题:你必须注释 C 函数返回类型,以便 ctypes 知道它是一个内存地址 - 否则默认情况下它是一个(4 字节)整数(而在任何 64 位操作系统中,指针是8 个字节长)。

然后您可以使用(隐藏的)创建 Python 端 POINT 结构POINT 类中的“from_address”方法:

test_lib.get_point.restype = c_void_p
p = POINT.from_address(test_lib.get_point())

print(p.x, p.y)

然而,在此之前,您在 C 端有一个更基本的问题:您在示例中声明的 POINT 结构仅在 get_point 运行时存在,并在之后被释放。上面的代码会导致段错误。

您的 C 代码必须正确分配内存。而且,您应该采取措施取消分配您在 C 中分配的数据结构 - 否则您将遇到内存泄漏,因为每次调用 C 中的函数都会分配更多内存,而您不会释放它。 (请注意,当 Python POINT 对象超出范围时,此内存不会自行释放)。

您的 C 代码可能是这样的:

#include <stdlib.h>
#include <stdio.h>

typedef struct point {
int x;
int y;
} POINT;

POINT *get_point()
{
POINT *p;
POINT initial = {1, 2};
p = malloc(sizeof(POINT));
*p = initial;
return p;
}

void free_point(POINT *p)
{
free(p);
}

还有这个 Python 部分:

from ctypes import *
import os

lib_name = '/testlib.so'
test_lib = CDLL(os.getcwd() + lib_name)

class POINT(Structure):
_fields_ = [('x', c_int),
('y', c_int)]

test_lib.get_point.restype = c_void_p

p1 = POINT.from_address( test_lib.get_point())
print (p1.x, p1.y)

test_lib.free_point(byref(p1))
del p1

一切都应该正常工作。

(为了让这个答案成为一个完整的 ctypes 示例,我将添加构建 teSTLib 文件的 GCC 命令:

gcc -c -fPIC test.c -o test.o
gcc test.o -shared -o testlib.so

)

关于python - 从库返回的 ctypes 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38661635/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com