C类型。如何通过引用传递结构?
Ctypes. How to pass struct by reference?
我尝试使用 ctypes 为 C 库编写 Python 包装器。
到目前为止我有:
C.h
typedef struct
{
int erorrCode;
char * Key;
} A;
#ifdef __cplusplus
extern "C" {
#endif
EXPORT void __stdcall DestroyA(A &input);
#ifdef __cplusplus
}
#endif
C.cpp
EXPORT void __stdcall DestroyA(A &input)
{
delete []input.Key;
}
Python.py
import sys
import ctypes
class A(ctypes.Structure):
_fields_ = [
("erorrCode", ctypes.c_int),
("Key", ctypes.c_char_p)]
try:
libapi = ctypes.cdll.LoadLibrary('./lib.so')
except OSError:
print("Unable to load RAPI library")
sys.exit()
DestroyA = libapi.DestroyA
libapi.DestroyA.argtypes = [ctypes.POINTER(A)]
libapi.DestroyA.restype = None
a = A(1,b'random_string')
DestroyA(ctypes.byref(a)) #!!!here is segmentation fault
那么,如何修复分段错误?
注意:我无法更改 C++ 端的代码,只要有办法在 Python 端修复它。
清单[Python.Docs]: ctypes - A foreign function library for Python。
这里有未定义的行为 (UB).
Python 为其对象提供内置内存管理,包括 CTypes 对象。
所以,每次对象 (PyObject 基本上是任何东西 - 包括 Python int), Python 在后台调用 malloc 函数族之一以分配内存。相反,当对象被销毁时(手动或通过GC),free被调用。
发生了什么:
- 您创建了对象(在幕后,Python分配了一些内存)
- 你在Python分配的对象上调用了free(这是错误的,更何况你还穿越了.dll 边界)
您需要调用 free 仅在您分配的指针上 。一个这样的例子:.
如果你想摆脱对象(从而释放它使用的内存),让Python为你做:
del a
补充说明:
您正在使用 __stdcall 函数和 ctypes.CDLL。同样,那是 UB(在 32 位 上)。使用“常规”调用约定 (__cdecl)
您正在传递参考。这是 C++ 特有的(尽管它只是一个 const ptr)。要与 C 兼容,请使用:
EXPORT void destroyA(A *pInput);
我尝试使用 ctypes 为 C 库编写 Python 包装器。 到目前为止我有:
C.h
typedef struct
{
int erorrCode;
char * Key;
} A;
#ifdef __cplusplus
extern "C" {
#endif
EXPORT void __stdcall DestroyA(A &input);
#ifdef __cplusplus
}
#endif
C.cpp
EXPORT void __stdcall DestroyA(A &input)
{
delete []input.Key;
}
Python.py
import sys
import ctypes
class A(ctypes.Structure):
_fields_ = [
("erorrCode", ctypes.c_int),
("Key", ctypes.c_char_p)]
try:
libapi = ctypes.cdll.LoadLibrary('./lib.so')
except OSError:
print("Unable to load RAPI library")
sys.exit()
DestroyA = libapi.DestroyA
libapi.DestroyA.argtypes = [ctypes.POINTER(A)]
libapi.DestroyA.restype = None
a = A(1,b'random_string')
DestroyA(ctypes.byref(a)) #!!!here is segmentation fault
那么,如何修复分段错误?
注意:我无法更改 C++ 端的代码,只要有办法在 Python 端修复它。
清单[Python.Docs]: ctypes - A foreign function library for Python。
这里有未定义的行为 (UB).
Python 为其对象提供内置内存管理,包括 CTypes 对象。
所以,每次对象 (PyObject 基本上是任何东西 - 包括 Python int), Python 在后台调用 malloc 函数族之一以分配内存。相反,当对象被销毁时(手动或通过GC),free被调用。
发生了什么:
- 您创建了对象(在幕后,Python分配了一些内存)
- 你在Python分配的对象上调用了free(这是错误的,更何况你还穿越了.dll 边界)
您需要调用 free 仅在您分配的指针上 。一个这样的例子:
如果你想摆脱对象(从而释放它使用的内存),让Python为你做:
del a
补充说明:
您正在使用 __stdcall 函数和 ctypes.CDLL。同样,那是 UB(在 32 位 上)。使用“常规”调用约定 (__cdecl)
您正在传递参考。这是 C++ 特有的(尽管它只是一个 const ptr)。要与 C 兼容,请使用:
EXPORT void destroyA(A *pInput);