tot*_*ter 7 c python ctypes wrapper python-2.7
给定一个简单的 C 文件:
#include <stdio.h>
typedef struct point {
int x;
int y;
} POINT;
POINT get_point()
{
POINT p = {1, 2};
return p;
}
Run Code Online (Sandbox Code Playgroud)
我有一个简单的 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())
Run Code Online (Sandbox Code Playgroud)
如何将返回值设置为POINT带有 value 的结构{1, 2}?
您所问的并不是您示例中的唯一问题。只是为了回答您首先提出的问题:您必须注释 C 函数返回类型,以便 ctypes 知道它是一个内存地址 - 否则默认情况下它是一个(4 字节)整数(而在任何 64 位操作系统中,指针是8 字节长)。
然后,您可以使用 POINT 类中的(隐藏)“from_address”方法创建 Python 端 POINT 结构:
test_lib.get_point.restype = c_void_p
p = POINT.from_address(test_lib.get_point())
print(p.x, p.y)
Run Code Online (Sandbox Code Playgroud)
然而,在此之前,您在 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);
}
Run Code Online (Sandbox Code Playgroud)
对于这个 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
Run Code Online (Sandbox Code Playgroud)
一切都应该正常。
(为了让这个答案是一个完整的 ctypes 示例,我将添加 GCC 命令来构建 testlib 文件:
gcc -c -fPIC test.c -o test.o
gcc test.o -shared -o testlib.so
Run Code Online (Sandbox Code Playgroud)
)
| 归档时间: |
|
| 查看次数: |
6356 次 |
| 最近记录: |