你問的是你的例子中唯一的問題。 只是爲了回答剛纔您的問題:您必須註釋C函數返回類型,以便ctypes知道它是一個內存地址 - 否則它默認爲(4字節)整數(而在任何64字節操作系統中,指針長8個字節)。
然後你就可以在你點類使用(隱藏) 「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)
之前的作品,但是,你有一個更根本的問題在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的例子,我將添加 GCC命令編譯TESTLIB文件:
gcc -c -fPIC test.c -o test.o
gcc test.o -shared -o testlib.so
)
您可以用標記爲'typedef的任何原因'ed'struct'?很無用。如果你不明白這個評論,你必須在開始之前學習'struct's和'typedef'。 – Olaf
@Olaf我一直使用'typedef'作爲C中'struct'的別名。那有什麼內在的錯誤嗎? –
我沒有評論使用'typedef'。但是你的評論證明我的假設是正確的。不要只遵循一種模式,但要學習**爲什麼**你必須/應該寫一些特定的方式! – Olaf