如何在 SWIG 中为 Python 创建时初始化 C 结构成员?
How to initialize C struct members at creation in SWIG for Python?
假设我们在 C 中有以下结构:
typedef struct buffer
{
uint8_t* const data;
const size_t maxSize;
size_t size;
} buffer_t;
我如何为此制作一个 SWIG 包装器,以便在 Python 中创建 buffer_t 时,它将给定数量的字节分配给数据指针并相应地设置 maxSize?
详情
所以基本上这里的问题与常量结构成员有关。默认情况下,SWIG 使用默认值初始化结构。这会导致问题:
StructWithConsts_t struct;
struct.constant = 5; // Error. This should've been set when creating the struct.
关于构造函数和析构函数的公认答案提供了此问题的解决方案。
我找到了一种解决方案,但由于指针类型转换,它相当老套。我不相信这是执行此操作的正确方法,但它有效:
在 .i 文件中,我使用 %inline 创建了一个包装器:
%inline %{
buffer_t* new_buffer(size_t size)
{
buffer_t* pBuffer = (buffer_t*)malloc(sizeof(buffer_t));
*(uint8_t**)&pBuffer->data = (uint8_t*)malloc(size * sizeof(uint8_t));
*(size_t*)&pBuffer->maxSize = size;
return (buffer_t*)pBuffer;
}
void free_buffer(buffer_t* pBuffer)
{
free(pBuffer->data);
free(pBuffer);
return;
}
%}
您可以在 SWIG 中将 C 结构视为 C++ 类,并使用创建者和破坏者方法扩展它们。
在你的情况下你的.i
应该有这个
typedef struct
{
uint8_t* const data;
const size_t maxSize;
size_t size;
} buffer_t;
%extend buffer_t {
buffer_t(size_t size)
{
buffer_t* pBuffer = malloc(sizeof *pBuffer);
pBuffer->data = malloc(size * sizeof (*pBuffer->data));
pBuffer->maxSize = size;
return pBuffer;
}
void ~buffer_t()
{
buffer_t *pBuffer = ($self);
free(pBuffer->data);
free(pBuffer);
return;
}
};
在python中会这样使用
from yourmodule import buffer_t
buffer = buffer_t(10)
垃圾收集器将负责释放内存。
还有其他方法可以做到这一点,但您没有可重现的示例来对其进行测试。
假设我们在 C 中有以下结构:
typedef struct buffer
{
uint8_t* const data;
const size_t maxSize;
size_t size;
} buffer_t;
我如何为此制作一个 SWIG 包装器,以便在 Python 中创建 buffer_t 时,它将给定数量的字节分配给数据指针并相应地设置 maxSize?
详情
所以基本上这里的问题与常量结构成员有关。默认情况下,SWIG 使用默认值初始化结构。这会导致问题:
StructWithConsts_t struct;
struct.constant = 5; // Error. This should've been set when creating the struct.
关于构造函数和析构函数的公认答案提供了此问题的解决方案。
我找到了一种解决方案,但由于指针类型转换,它相当老套。我不相信这是执行此操作的正确方法,但它有效:
在 .i 文件中,我使用 %inline 创建了一个包装器:
%inline %{
buffer_t* new_buffer(size_t size)
{
buffer_t* pBuffer = (buffer_t*)malloc(sizeof(buffer_t));
*(uint8_t**)&pBuffer->data = (uint8_t*)malloc(size * sizeof(uint8_t));
*(size_t*)&pBuffer->maxSize = size;
return (buffer_t*)pBuffer;
}
void free_buffer(buffer_t* pBuffer)
{
free(pBuffer->data);
free(pBuffer);
return;
}
%}
您可以在 SWIG 中将 C 结构视为 C++ 类,并使用创建者和破坏者方法扩展它们。
在你的情况下你的.i
应该有这个
typedef struct
{
uint8_t* const data;
const size_t maxSize;
size_t size;
} buffer_t;
%extend buffer_t {
buffer_t(size_t size)
{
buffer_t* pBuffer = malloc(sizeof *pBuffer);
pBuffer->data = malloc(size * sizeof (*pBuffer->data));
pBuffer->maxSize = size;
return pBuffer;
}
void ~buffer_t()
{
buffer_t *pBuffer = ($self);
free(pBuffer->data);
free(pBuffer);
return;
}
};
在python中会这样使用
from yourmodule import buffer_t
buffer = buffer_t(10)
垃圾收集器将负责释放内存。
还有其他方法可以做到这一点,但您没有可重现的示例来对其进行测试。